diff options
Diffstat (limited to 'tests')
163 files changed, 9796 insertions, 5177 deletions
diff --git a/tests/00modules-test b/tests/00modules-test index 64e054a..f816b80 100755 --- a/tests/00modules-test +++ b/tests/00modules-test @@ -23,12 +23,16 @@ if [ -f /etc/os-release ] ; then fi echo "Memory" -free -h +free -m pversion cryptsetup pversion veritysetup pversion integritysetup -pversion cryptsetup-reencrypt + +[ -x $CRYPTSETUP_PATH/cryptsetup ] && { + echo -e "Cryptsetup defaults:" + $CRYPTSETUP_PATH/cryptsetup --help | sed -n '/optional key file for/,$p' | tail -n +3 +} [ $(id -u) != 0 ] && exit 77 diff --git a/tests/Makefile.am b/tests/Makefile.am index 4688bff..c8a46a8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,7 @@ TESTS = 00modules-test \ api-test \ api-test-2 \ + compat-args-test \ compat-test \ compat-test2 \ loopaes-test \ @@ -17,30 +18,55 @@ TESTS = 00modules-test \ luks2-validation-test \ luks2-integrity-test \ vectors-test \ - blockwise-compat \ - bitlk-compat-test + blockwise-compat-test \ + bitlk-compat-test \ + fvault2-compat-test \ + run-all-symbols \ + unit-utils-crypt-test \ + unit-wipe-test \ + reencryption-compat-test \ + luks2-reencryption-test \ + luks2-reencryption-mangle-test if VERITYSETUP TESTS += verity-compat-test endif -if REENCRYPT -TESTS += reencryption-compat-test reencryption-compat-test2 luks2-reencryption-test luks2-reencryption-mangle-test -endif - if INTEGRITYSETUP TESTS += integrity-compat-test endif +if SSHPLUGIN_TOKEN +TESTS += ssh-test-plugin +endif + +if EXTERNAL_TOKENS +TESTS += systemd-test-plugin +endif + +ssh-test-plugin: fake_token_path.so +systemd-test-plugin: fake_token_path.so fake_systemd_tpm_path.so + +# Do not use global CFLAGS here as the *.so link does not support sanitizers +fake_token_path.so: fake_token_path.c + $(CC) $(LDFLAGS) -I $(top_srcdir)/lib -fPIC -shared -D_GNU_SOURCE \ + -Wl,--version-script=$(top_srcdir)/lib/libcryptsetup.sym \ + -o fake_token_path.so $(top_srcdir)/tests/fake_token_path.c \ + -DBUILD_DIR=\"$(abs_top_srcdir)/.libs/\" + +fake_systemd_tpm_path.so: fake_systemd_tpm_path.c + $(CC) $(LDFLAGS) -fPIC -shared -D_GNU_SOURCE -o fake_systemd_tpm_path.so \ + $(top_srcdir)/tests/fake_systemd_tpm_path.c + EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ compatimage2.img.xz \ conversion_imgs.tar.xz \ luks2_keyslot_unassigned.img.xz \ img_fs_ext4.img.xz img_fs_vfat.img.xz img_fs_xfs.img.xz \ + xfs_512_block_size.img.xz \ valid_header_file.xz \ luks2_valid_hdr.img.xz \ - luks2_header_requirements.xz \ - luks2_header_requirements_free.xz \ + luks2_header_requirements.tar.xz \ luks2_mda_images.tar.xz \ evil_hdr-payload_overwrite.xz \ evil_hdr-stripes_payload_dmg.xz \ @@ -50,12 +76,12 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ tcrypt-images.tar.xz \ luks1-images.tar.xz \ 00modules-test \ + compat-args-test \ compat-test \ compat-test2 \ loopaes-test align-test discards-test mode-test password-hash-test \ align-test2 verity-compat-test \ reencryption-compat-test \ - reencryption-compat-test2 \ luks2-reencryption-test \ luks2-reencryption-mangle-test \ tcrypt-compat-test \ @@ -67,37 +93,44 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ keyring-compat-test \ integrity-compat-test \ cryptsetup-valg-supps valg.sh valg-api.sh \ - blockwise-compat \ + blockwise-compat-test \ blkid-luks2-pv.img.xz \ Makefile.localtest \ bitlk-compat-test \ - bitlk-images.tar.xz - -CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log + bitlk-images.tar.xz \ + fvault2-compat-test \ + fvault2-images.tar.xz \ + ssh-test-plugin \ + generate-symbols-list \ + run-all-symbols \ + fake_token_path.c \ + fake_systemd_tpm_path.c \ + unit-wipe-test \ + systemd-test-plugin + +CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log test-symbols-list.h fake_token_path.so fake_systemd_tpm_path.so 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) + -rm -rf tcrypt-images luks1-images luks2-images bitlk-images fvault2-images conversion_imgs luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp external-tokens differ_SOURCES = differ.c differ_CFLAGS = $(AM_CFLAGS) -Wall -O2 api_test_SOURCES = api-test.c api_test.h test_utils.c -api_test_LDADD = $(LDADD) ../libcryptsetup.la +api_test_LDADD = ../libcryptsetup.la api_test_LDFLAGS = $(AM_LDFLAGS) -static -api_test_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1 +api_test_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib api_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h api_test_2_SOURCES = api-test-2.c api_test.h test_utils.c -api_test_2_LDADD = $(LDADD) ../libcryptsetup.la +api_test_2_LDADD = ../libcryptsetup.la api_test_2_LDFLAGS = $(AM_LDFLAGS) -static -api_test_2_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1 +api_test_2_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib api_test_2_CPPFLAGS = $(AM_CPPFLAGS) -include config.h vectors_test_SOURCES = crypto-vectors.c vectors_test_LDADD = ../libcrypto_backend.la @CRYPTO_LIBS@ @LIBARGON2_LIBS@ vectors_test_LDFLAGS = $(AM_LDFLAGS) -static -vectors_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib/crypto_backend/ @CRYPTO_CFLAGS@ +vectors_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib @CRYPTO_CFLAGS@ vectors_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h unit_utils_io_SOURCES = unit-utils-io.c @@ -106,7 +139,33 @@ unit_utils_io_LDFLAGS = $(AM_LDFLAGS) -static unit_utils_io_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib unit_utils_io_CPPFLAGS = $(AM_CPPFLAGS) -include config.h -check_PROGRAMS = api-test api-test-2 differ vectors-test unit-utils-io +unit_utils_crypt_test_SOURCES = unit-utils-crypt.c ../lib/utils_crypt.c ../lib/utils_crypt.h +unit_utils_crypt_test_LDADD = ../libcryptsetup.la +unit_utils_crypt_test_LDFLAGS = $(AM_LDFLAGS) -static +unit_utils_crypt_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib +unit_utils_crypt_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h + +unit_wipe_SOURCES = unit-wipe.c +unit_wipe_LDADD = ../libcryptsetup.la +unit_wipe_LDFLAGS = $(AM_LDFLAGS) -static +unit_wipe_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib +unit_wipe_CPPFLAGS = $(AM_CPPFLAGS) + +BUILT_SOURCES = test-symbols-list.h + +test-symbols-list.h: $(top_srcdir)/lib/libcryptsetup.sym generate-symbols-list + $(srcdir)/generate-symbols-list $(top_srcdir)/lib/libcryptsetup.sym > $(builddir)/test-symbols-list.h + +all_symbols_test_SOURCES = all-symbols-test.c +nodist_all_symbols_test_SOURCES = test-symbols-list.h +all_symbols_test.$(OBJEXT): test-symbols-list.h +all_symbols_test_LDFLAGS = $(AM_LDFLAGS) -ldl +all_symbols_test_CFLAGS = $(AM_CFLAGS) +all_symbols_test_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE + +check_PROGRAMS = api-test api-test-2 differ vectors-test unit-utils-io unit-utils-crypt-test unit-wipe all-symbols-test + +check-programs: test-symbols-list.h $(check_PROGRAMS) fake_token_path.so fake_systemd_tpm_path.so conversion_imgs: @tar xJf conversion_imgs.tar.xz @@ -115,6 +174,7 @@ compatimage.img: @xz -k -d compatimage.img.xz valgrind-check: api-test api-test-2 differ + @VALG=1 ./compat-args-test @VALG=1 ./compat-test @VALG=1 ./compat-test2 @VALG=1 ./luks2-validation-test @@ -125,6 +185,22 @@ valgrind-check: api-test api-test-2 differ @VALG=1 ./luks2-reencryption-test @VALG=1 ./luks2-reencryption-mangle-test @VALG=1 ./bitlk-compat-test - @grep -l "ERROR SUMMARY: [^0] errors" valglog* || echo "No leaks detected." + @VALG=1 ./tcrypt-compat-test + @VALG=1 ./align-test + @VALG=1 ./align-test2 + @VALG=1 ./device-test + @VALG=1 ./discards-test + @VALG=1 ./keyring-compat-test + @VALG=1 ./loopaes-test + @VALG=1 ./luks1-compat-test + @VALG=1 ./luks2-integrity-test + @VALG=1 ./mode-test + @VALG=1 ./password-hash-test + @VALG=1 ./reencryption-compat-test + @VALG=1 ./fvault2-compat-test + @[ -z "$RUN_SSH_PLUGIN_TEST" ] || VALG=1 ./ssh-test-plugin + @INFOSTRING="unit-utils-crypt-test" ./valg-api.sh ./unit-utils-crypt-test + @INFOSTRING="vectors-test" ./valg-api.sh ./vectors-test + @grep -l "ERROR SUMMARY: [^0][0-9]* errors" valglog* || echo "No leaks detected." .PHONY: valgrind-check diff --git a/tests/Makefile.in b/tests/Makefile.in deleted file mode 100644 index c63cdc3..0000000 --- a/tests/Makefile.in +++ /dev/null @@ -1,1040 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# 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, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -TESTS = 00modules-test api-test$(EXEEXT) api-test-2$(EXEEXT) \ - compat-test compat-test2 loopaes-test align-test align-test2 \ - discards-test mode-test password-hash-test tcrypt-compat-test \ - luks1-compat-test device-test keyring-test keyring-compat-test \ - luks2-validation-test luks2-integrity-test \ - 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 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) -subdir = tests -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -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) -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 -am__v_lt_1 = -api_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(api_test_CFLAGS) \ - $(CFLAGS) $(api_test_LDFLAGS) $(LDFLAGS) -o $@ -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 = $(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 $@ -am_unit_utils_io_OBJECTS = unit_utils_io-unit-utils-io.$(OBJEXT) -unit_utils_io_OBJECTS = $(am_unit_utils_io_OBJECTS) -unit_utils_io_DEPENDENCIES = ../libutils_io.la -unit_utils_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(unit_utils_io_CFLAGS) \ - $(CFLAGS) $(unit_utils_io_LDFLAGS) $(LDFLAGS) -o $@ -am_vectors_test_OBJECTS = vectors_test-crypto-vectors.$(OBJEXT) -vectors_test_OBJECTS = $(am_vectors_test_OBJECTS) -vectors_test_DEPENDENCIES = ../libcrypto_backend.la -vectors_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(vectors_test_CFLAGS) \ - $(CFLAGS) $(vectors_test_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/api_test-api-test.Po \ - ./$(DEPDIR)/api_test-test_utils.Po \ - ./$(DEPDIR)/api_test_2-api-test-2.Po \ - ./$(DEPDIR)/api_test_2-test_utils.Po \ - ./$(DEPDIR)/differ-differ.Po \ - ./$(DEPDIR)/unit_utils_io-unit-utils-io.Po \ - ./$(DEPDIR)/vectors_test-crypto-vectors.Po -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(api_test_SOURCES) $(api_test_2_SOURCES) $(differ_SOURCES) \ - $(unit_utils_io_SOURCES) $(vectors_test_SOURCES) -DIST_SOURCES = $(api_test_SOURCES) $(api_test_2_SOURCES) \ - $(differ_SOURCES) $(unit_utils_io_SOURCES) \ - $(vectors_test_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BLKID_CFLAGS = @BLKID_CFLAGS@ -BLKID_LIBS = @BLKID_LIBS@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -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@ -DEFAULT_TMPFILESDIR = @DEFAULT_TMPFILESDIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DEVMAPPER_CFLAGS = @DEVMAPPER_CFLAGS@ -DEVMAPPER_LIBS = @DEVMAPPER_LIBS@ -DEVMAPPER_STATIC_CFLAGS = @DEVMAPPER_STATIC_CFLAGS@ -DEVMAPPER_STATIC_LIBS = @DEVMAPPER_STATIC_LIBS@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -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@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTLLIBS = @INTLLIBS@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -JSON_C_CFLAGS = @JSON_C_CFLAGS@ -JSON_C_LIBS = @JSON_C_LIBS@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBARGON2_CFLAGS = @LIBARGON2_CFLAGS@ -LIBARGON2_LIBS = @LIBARGON2_LIBS@ -LIBCRYPTSETUP_VERSION = @LIBCRYPTSETUP_VERSION@ -LIBCRYPTSETUP_VERSION_INFO = @LIBCRYPTSETUP_VERSION_INFO@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NSS_CFLAGS = @NSS_CFLAGS@ -NSS_LIBS = @NSS_LIBS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ -OPENSSL_LIBS = @OPENSSL_LIBS@ -OPENSSL_STATIC_CFLAGS = @OPENSSL_STATIC_CFLAGS@ -OPENSSL_STATIC_LIBS = @OPENSSL_STATIC_LIBS@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PASSWDQC_LIBS = @PASSWDQC_LIBS@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POPT_LIBS = @POPT_LIBS@ -POSUB = @POSUB@ -PWQUALITY_CFLAGS = @PWQUALITY_CFLAGS@ -PWQUALITY_LIBS = @PWQUALITY_LIBS@ -PWQUALITY_STATIC_LIBS = @PWQUALITY_STATIC_LIBS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -UUID_LIBS = @UUID_LIBS@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -systemd_tmpfilesdir = @systemd_tmpfilesdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ - compatimage2.img.xz \ - conversion_imgs.tar.xz \ - luks2_keyslot_unassigned.img.xz \ - img_fs_ext4.img.xz img_fs_vfat.img.xz img_fs_xfs.img.xz \ - valid_header_file.xz \ - luks2_valid_hdr.img.xz \ - luks2_header_requirements.xz \ - luks2_header_requirements_free.xz \ - luks2_mda_images.tar.xz \ - evil_hdr-payload_overwrite.xz \ - evil_hdr-stripes_payload_dmg.xz \ - evil_hdr-luks_hdr_damage.xz \ - evil_hdr-small_luks_device.xz \ - evil_hdr-keyslot_overlap.xz \ - tcrypt-images.tar.xz \ - luks1-images.tar.xz \ - 00modules-test \ - compat-test \ - compat-test2 \ - loopaes-test align-test discards-test mode-test password-hash-test \ - align-test2 verity-compat-test \ - reencryption-compat-test \ - reencryption-compat-test2 \ - luks2-reencryption-test \ - luks2-reencryption-mangle-test \ - tcrypt-compat-test \ - luks1-compat-test \ - luks2-validation-test generators \ - luks2-integrity-test \ - device-test \ - keyring-test \ - keyring-compat-test \ - integrity-compat-test \ - cryptsetup-valg-supps valg.sh valg-api.sh \ - blockwise-compat \ - blkid-luks2-pv.img.xz \ - Makefile.localtest \ - bitlk-compat-test \ - 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 -api_test_LDADD = $(LDADD) ../libcryptsetup.la -api_test_LDFLAGS = $(AM_LDFLAGS) -static -api_test_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1 -api_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h -api_test_2_SOURCES = api-test-2.c api_test.h test_utils.c -api_test_2_LDADD = $(LDADD) ../libcryptsetup.la -api_test_2_LDFLAGS = $(AM_LDFLAGS) -static -api_test_2_CFLAGS = -g -Wall -O0 $(AM_CFLAGS) -I$(top_srcdir)/lib/ -I$(top_srcdir)/lib/luks1 -api_test_2_CPPFLAGS = $(AM_CPPFLAGS) -include config.h -vectors_test_SOURCES = crypto-vectors.c -vectors_test_LDADD = ../libcrypto_backend.la @CRYPTO_LIBS@ @LIBARGON2_LIBS@ -vectors_test_LDFLAGS = $(AM_LDFLAGS) -static -vectors_test_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib/crypto_backend/ @CRYPTO_CFLAGS@ -vectors_test_CPPFLAGS = $(AM_CPPFLAGS) -include config.h -unit_utils_io_SOURCES = unit-utils-io.c -unit_utils_io_LDADD = ../libutils_io.la -unit_utils_io_LDFLAGS = $(AM_LDFLAGS) -static -unit_utils_io_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib -unit_utils_io_CPPFLAGS = $(AM_CPPFLAGS) -include config.h -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu tests/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -api-test$(EXEEXT): $(api_test_OBJECTS) $(api_test_DEPENDENCIES) $(EXTRA_api_test_DEPENDENCIES) - @rm -f api-test$(EXEEXT) - $(AM_V_CCLD)$(api_test_LINK) $(api_test_OBJECTS) $(api_test_LDADD) $(LIBS) - -api-test-2$(EXEEXT): $(api_test_2_OBJECTS) $(api_test_2_DEPENDENCIES) $(EXTRA_api_test_2_DEPENDENCIES) - @rm -f api-test-2$(EXEEXT) - $(AM_V_CCLD)$(api_test_2_LINK) $(api_test_2_OBJECTS) $(api_test_2_LDADD) $(LIBS) - -differ$(EXEEXT): $(differ_OBJECTS) $(differ_DEPENDENCIES) $(EXTRA_differ_DEPENDENCIES) - @rm -f differ$(EXEEXT) - $(AM_V_CCLD)$(differ_LINK) $(differ_OBJECTS) $(differ_LDADD) $(LIBS) - -unit-utils-io$(EXEEXT): $(unit_utils_io_OBJECTS) $(unit_utils_io_DEPENDENCIES) $(EXTRA_unit_utils_io_DEPENDENCIES) - @rm -f unit-utils-io$(EXEEXT) - $(AM_V_CCLD)$(unit_utils_io_LINK) $(unit_utils_io_OBJECTS) $(unit_utils_io_LDADD) $(LIBS) - -vectors-test$(EXEEXT): $(vectors_test_OBJECTS) $(vectors_test_DEPENDENCIES) $(EXTRA_vectors_test_DEPENDENCIES) - @rm -f vectors-test$(EXEEXT) - $(AM_V_CCLD)$(vectors_test_LINK) $(vectors_test_OBJECTS) $(vectors_test_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api_test-api-test.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api_test_2-api-test-2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/api_test_2-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/differ-differ.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_utils_io-unit-utils-io.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vectors_test-crypto-vectors.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -api_test-api-test.o: api-test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -MT api_test-api-test.o -MD -MP -MF $(DEPDIR)/api_test-api-test.Tpo -c -o api_test-api-test.o `test -f 'api-test.c' || echo '$(srcdir)/'`api-test.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test-api-test.Tpo $(DEPDIR)/api_test-api-test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='api-test.c' object='api_test-api-test.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -c -o api_test-api-test.o `test -f 'api-test.c' || echo '$(srcdir)/'`api-test.c - -api_test-api-test.obj: api-test.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -MT api_test-api-test.obj -MD -MP -MF $(DEPDIR)/api_test-api-test.Tpo -c -o api_test-api-test.obj `if test -f 'api-test.c'; then $(CYGPATH_W) 'api-test.c'; else $(CYGPATH_W) '$(srcdir)/api-test.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test-api-test.Tpo $(DEPDIR)/api_test-api-test.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='api-test.c' object='api_test-api-test.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -c -o api_test-api-test.obj `if test -f 'api-test.c'; then $(CYGPATH_W) 'api-test.c'; else $(CYGPATH_W) '$(srcdir)/api-test.c'; fi` - -api_test-test_utils.o: test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -MT api_test-test_utils.o -MD -MP -MF $(DEPDIR)/api_test-test_utils.Tpo -c -o api_test-test_utils.o `test -f 'test_utils.c' || echo '$(srcdir)/'`test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test-test_utils.Tpo $(DEPDIR)/api_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils.c' object='api_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -c -o api_test-test_utils.o `test -f 'test_utils.c' || echo '$(srcdir)/'`test_utils.c - -api_test-test_utils.obj: test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -MT api_test-test_utils.obj -MD -MP -MF $(DEPDIR)/api_test-test_utils.Tpo -c -o api_test-test_utils.obj `if test -f 'test_utils.c'; then $(CYGPATH_W) 'test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test-test_utils.Tpo $(DEPDIR)/api_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils.c' object='api_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_CPPFLAGS) $(CPPFLAGS) $(api_test_CFLAGS) $(CFLAGS) -c -o api_test-test_utils.obj `if test -f 'test_utils.c'; then $(CYGPATH_W) 'test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils.c'; fi` - -api_test_2-api-test-2.o: api-test-2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -MT api_test_2-api-test-2.o -MD -MP -MF $(DEPDIR)/api_test_2-api-test-2.Tpo -c -o api_test_2-api-test-2.o `test -f 'api-test-2.c' || echo '$(srcdir)/'`api-test-2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test_2-api-test-2.Tpo $(DEPDIR)/api_test_2-api-test-2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='api-test-2.c' object='api_test_2-api-test-2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -c -o api_test_2-api-test-2.o `test -f 'api-test-2.c' || echo '$(srcdir)/'`api-test-2.c - -api_test_2-api-test-2.obj: api-test-2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -MT api_test_2-api-test-2.obj -MD -MP -MF $(DEPDIR)/api_test_2-api-test-2.Tpo -c -o api_test_2-api-test-2.obj `if test -f 'api-test-2.c'; then $(CYGPATH_W) 'api-test-2.c'; else $(CYGPATH_W) '$(srcdir)/api-test-2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test_2-api-test-2.Tpo $(DEPDIR)/api_test_2-api-test-2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='api-test-2.c' object='api_test_2-api-test-2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -c -o api_test_2-api-test-2.obj `if test -f 'api-test-2.c'; then $(CYGPATH_W) 'api-test-2.c'; else $(CYGPATH_W) '$(srcdir)/api-test-2.c'; fi` - -api_test_2-test_utils.o: test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -MT api_test_2-test_utils.o -MD -MP -MF $(DEPDIR)/api_test_2-test_utils.Tpo -c -o api_test_2-test_utils.o `test -f 'test_utils.c' || echo '$(srcdir)/'`test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test_2-test_utils.Tpo $(DEPDIR)/api_test_2-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils.c' object='api_test_2-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -c -o api_test_2-test_utils.o `test -f 'test_utils.c' || echo '$(srcdir)/'`test_utils.c - -api_test_2-test_utils.obj: test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -MT api_test_2-test_utils.obj -MD -MP -MF $(DEPDIR)/api_test_2-test_utils.Tpo -c -o api_test_2-test_utils.obj `if test -f 'test_utils.c'; then $(CYGPATH_W) 'test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/api_test_2-test_utils.Tpo $(DEPDIR)/api_test_2-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils.c' object='api_test_2-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(api_test_2_CPPFLAGS) $(CPPFLAGS) $(api_test_2_CFLAGS) $(CFLAGS) -c -o api_test_2-test_utils.obj `if test -f 'test_utils.c'; then $(CYGPATH_W) 'test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils.c'; fi` - -differ-differ.o: differ.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(differ_CFLAGS) $(CFLAGS) -MT differ-differ.o -MD -MP -MF $(DEPDIR)/differ-differ.Tpo -c -o differ-differ.o `test -f 'differ.c' || echo '$(srcdir)/'`differ.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/differ-differ.Tpo $(DEPDIR)/differ-differ.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='differ.c' object='differ-differ.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(differ_CFLAGS) $(CFLAGS) -c -o differ-differ.o `test -f 'differ.c' || echo '$(srcdir)/'`differ.c - -differ-differ.obj: differ.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(differ_CFLAGS) $(CFLAGS) -MT differ-differ.obj -MD -MP -MF $(DEPDIR)/differ-differ.Tpo -c -o differ-differ.obj `if test -f 'differ.c'; then $(CYGPATH_W) 'differ.c'; else $(CYGPATH_W) '$(srcdir)/differ.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/differ-differ.Tpo $(DEPDIR)/differ-differ.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='differ.c' object='differ-differ.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(differ_CFLAGS) $(CFLAGS) -c -o differ-differ.obj `if test -f 'differ.c'; then $(CYGPATH_W) 'differ.c'; else $(CYGPATH_W) '$(srcdir)/differ.c'; fi` - -unit_utils_io-unit-utils-io.o: unit-utils-io.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unit_utils_io_CPPFLAGS) $(CPPFLAGS) $(unit_utils_io_CFLAGS) $(CFLAGS) -MT unit_utils_io-unit-utils-io.o -MD -MP -MF $(DEPDIR)/unit_utils_io-unit-utils-io.Tpo -c -o unit_utils_io-unit-utils-io.o `test -f 'unit-utils-io.c' || echo '$(srcdir)/'`unit-utils-io.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unit_utils_io-unit-utils-io.Tpo $(DEPDIR)/unit_utils_io-unit-utils-io.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unit-utils-io.c' object='unit_utils_io-unit-utils-io.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unit_utils_io_CPPFLAGS) $(CPPFLAGS) $(unit_utils_io_CFLAGS) $(CFLAGS) -c -o unit_utils_io-unit-utils-io.o `test -f 'unit-utils-io.c' || echo '$(srcdir)/'`unit-utils-io.c - -unit_utils_io-unit-utils-io.obj: unit-utils-io.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unit_utils_io_CPPFLAGS) $(CPPFLAGS) $(unit_utils_io_CFLAGS) $(CFLAGS) -MT unit_utils_io-unit-utils-io.obj -MD -MP -MF $(DEPDIR)/unit_utils_io-unit-utils-io.Tpo -c -o unit_utils_io-unit-utils-io.obj `if test -f 'unit-utils-io.c'; then $(CYGPATH_W) 'unit-utils-io.c'; else $(CYGPATH_W) '$(srcdir)/unit-utils-io.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unit_utils_io-unit-utils-io.Tpo $(DEPDIR)/unit_utils_io-unit-utils-io.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unit-utils-io.c' object='unit_utils_io-unit-utils-io.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(unit_utils_io_CPPFLAGS) $(CPPFLAGS) $(unit_utils_io_CFLAGS) $(CFLAGS) -c -o unit_utils_io-unit-utils-io.obj `if test -f 'unit-utils-io.c'; then $(CYGPATH_W) 'unit-utils-io.c'; else $(CYGPATH_W) '$(srcdir)/unit-utils-io.c'; fi` - -vectors_test-crypto-vectors.o: crypto-vectors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vectors_test_CPPFLAGS) $(CPPFLAGS) $(vectors_test_CFLAGS) $(CFLAGS) -MT vectors_test-crypto-vectors.o -MD -MP -MF $(DEPDIR)/vectors_test-crypto-vectors.Tpo -c -o vectors_test-crypto-vectors.o `test -f 'crypto-vectors.c' || echo '$(srcdir)/'`crypto-vectors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vectors_test-crypto-vectors.Tpo $(DEPDIR)/vectors_test-crypto-vectors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto-vectors.c' object='vectors_test-crypto-vectors.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vectors_test_CPPFLAGS) $(CPPFLAGS) $(vectors_test_CFLAGS) $(CFLAGS) -c -o vectors_test-crypto-vectors.o `test -f 'crypto-vectors.c' || echo '$(srcdir)/'`crypto-vectors.c - -vectors_test-crypto-vectors.obj: crypto-vectors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vectors_test_CPPFLAGS) $(CPPFLAGS) $(vectors_test_CFLAGS) $(CFLAGS) -MT vectors_test-crypto-vectors.obj -MD -MP -MF $(DEPDIR)/vectors_test-crypto-vectors.Tpo -c -o vectors_test-crypto-vectors.obj `if test -f 'crypto-vectors.c'; then $(CYGPATH_W) 'crypto-vectors.c'; else $(CYGPATH_W) '$(srcdir)/crypto-vectors.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vectors_test-crypto-vectors.Tpo $(DEPDIR)/vectors_test-crypto-vectors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto-vectors.c' object='vectors_test-crypto-vectors.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(vectors_test_CPPFLAGS) $(CPPFLAGS) $(vectors_test_CFLAGS) $(CFLAGS) -c -o vectors_test-crypto-vectors.obj `if test -f 'crypto-vectors.c'; then $(CYGPATH_W) 'crypto-vectors.c'; else $(CYGPATH_W) '$(srcdir)/crypto-vectors.c'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ - else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/api_test-api-test.Po - -rm -f ./$(DEPDIR)/api_test-test_utils.Po - -rm -f ./$(DEPDIR)/api_test_2-api-test-2.Po - -rm -f ./$(DEPDIR)/api_test_2-test_utils.Po - -rm -f ./$(DEPDIR)/differ-differ.Po - -rm -f ./$(DEPDIR)/unit_utils_io-unit-utils-io.Po - -rm -f ./$(DEPDIR)/vectors_test-crypto-vectors.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/api_test-api-test.Po - -rm -f ./$(DEPDIR)/api_test-test_utils.Po - -rm -f ./$(DEPDIR)/api_test_2-api-test-2.Po - -rm -f ./$(DEPDIR)/api_test_2-test_utils.Po - -rm -f ./$(DEPDIR)/differ-differ.Po - -rm -f ./$(DEPDIR)/unit_utils_io-unit-utils-io.Po - -rm -f ./$(DEPDIR)/vectors_test-crypto-vectors.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ - check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ - clean-local cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - -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 - -conversion_imgs: - @tar xJf conversion_imgs.tar.xz - -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 - @VALG=1 ./integrity-compat-test - @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 ./luks2-reencryption-mangle-test - @VALG=1 ./bitlk-compat-test - @grep -l "ERROR SUMMARY: [^0] errors" valglog* || echo "No leaks detected." - -.PHONY: valgrind-check - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tests/Makefile.localtest b/tests/Makefile.localtest index 29a62f3..89ce2c3 100644 --- a/tests/Makefile.localtest +++ b/tests/Makefile.localtest @@ -1,11 +1,25 @@ # # Makefile to run tests with system binaries # USE: make -f Makefile.localtest tests CRYPTSETUP_PATH=/sbin +# (append TESTSUITE_NOSKIP=y to avoid treating skipped tests as success) # -CPPFLAGS=-I../lib/ -I../lib/luks1 -DHAVE_DECL_DM_TASK_RETRY_REMOVE -DKERNEL_KEYRING -DHAVE_SYS_SYSMACROS_H -DNO_CRYPTSETUP_PATH -CFLAGS=-O2 -g -Wall +CPPFLAGS=-I../lib/ -I../lib/luks1 -DHAVE_DECL_DM_TASK_RETRY_REMOVE -DKERNEL_KEYRING \ + -DHAVE_SYS_SYSMACROS_H -DNO_CRYPTSETUP_PATH +CFLAGS=-O2 -g -Wall -D_GNU_SOURCE LDLIBS=-lcryptsetup -ldevmapper -TESTS=$(wildcard *-test *-test2) api-test api-test-2 +TESTS=$(wildcard *-test *-test2) api-test api-test-2 all-symbols-test unit-utils-crypt-test +TESTS_UTILS=differ unit-utils-io unit-wipe + +ifneq ($(RUN_SSH_PLUGIN_TEST),) +TESTS += ssh-test-plugin +endif + +ifneq ($(RUN_SYSTEMD_PLUGIN_TEST),) +TESTS += systemd-test-plugin +TESTS_UTILS += fake_systemd_tpm_path.so +endif + +check-programs: $(TESTS_UTILS) $(TESTS) differ: differ.o $(CC) -o $@ $^ @@ -16,15 +30,37 @@ api-test: api-test.o test_utils.o api-test-2: api-test-2.o test_utils.o $(CC) -o $@ $^ $(LDLIBS) -tests: differ $(TESTS) +unit-wipe: unit-wipe.o + $(CC) -o $@ $^ $(LDLIBS) + +unit-utils-io: unit-utils-io.o ../lib/utils_io.o + $(CC) -o $@ $^ + +unit-utils-crypt-test: unit-utils-crypt.o ../lib/utils_crypt.o + $(CC) -o $@ $^ $(LDLIBS) + +test-symbols-list.h: generate-symbols-list + ./generate-symbols-list ../lib/libcryptsetup.sym > test-symbols-list.h + +all-symbols-test.o: test-symbols-list.h + $(CC) -c $*.c + +all-symbols-test: all-symbols-test.o + $(CC) -o $@ $^ -ldl + +fake_systemd_tpm_path.so: fake_systemd_tpm_path.c + $(CC) -fPIC -shared -D_GNU_SOURCE -o fake_systemd_tpm_path.so fake_systemd_tpm_path.c + +tests: $(TESTS_UTILS) $(TESTS) @for test in $(sort $(TESTS)); do \ echo [$$test]; \ ./$$test; \ - [ $$? -ne 77 -a $$? -ne 0 ] && exit 1; \ + [ $(if $(TESTSUITE_NOSKIP),,$$? -ne 77 -a) $$? -ne 0 ] && exit 1; \ true; \ done; clean: - rm -f *.o differ api-test api-test-2 + rm -f *.o $(TESTS_UTILS) api-test api-test-2 unit-utils-crypt-test \ + all-symbols-test test-symbols-list.h .PHONY: clean diff --git a/tests/align-test b/tests/align-test index ac3af88..5941cde 100755 --- a/tests/align-test +++ b/tests/align-test @@ -10,17 +10,27 @@ PWD1="93R4P4pIqAH8" PWD2="mymJeD8ivEhE" FAST_PBKDF="--pbkdf-force-iterations 1000" +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + +function fips_mode() +{ + [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] +} + cleanup() { udevadm settle >/dev/null 2>&1 if [ -d "$MNT_DIR" ] ; then - umount -f $MNT_DIR 2>/dev/null - rmdir $MNT_DIR 2>/dev/null + umount -f $MNT_DIR 2>/dev/null + rmdir $MNT_DIR 2>/dev/null fi [ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 # FIXME scsi_debug sometimes in-use here sleep 1 - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 sleep 1 } @@ -37,7 +47,19 @@ skip() { echo "TEST SKIPPED: $1" cleanup - exit 0 + exit 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } function dm_crypt_features() @@ -64,7 +86,7 @@ function dm_crypt_features() } add_device() { - modprobe scsi_debug $@ delay=0 + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "This kernel seems to not support proper scsi_debug module, test skipped." exit 77 @@ -104,7 +126,7 @@ format() # key_bits expected [forced] [ $ALIGN -ne $2 ] && fail "Expected alignment differs: expected $2 != detected $ALIGN" # test some operation, just in case - echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1 + echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --new-key-slot 1 [ $? -ne 0 ] && fail "Keyslot add failed." $CRYPTSETUP -q luksKillSlot $DEV 1 @@ -137,7 +159,7 @@ format_null() [ $POFF != $2 ] && fail "Expected data offset differs: expected $2 != detected $POFF" if [ -n "$4" ] ; then for j in 1 2 3 4 5 6 7 ; do - echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF --key-slot $j -c null $PARAMS + echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF --new-key-slot $j -c null $PARAMS echo -n $j [ $? -ne 0 ] && fail done @@ -173,14 +195,20 @@ format_plain_fail() # sector size fi } +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 fi dm_crypt_features -modprobe --dry-run scsi_debug || exit 77 +modprobe --dry-run scsi_debug >/dev/null 2>&1 || skip "This kernel seems to not support proper scsi_debug module, test skipped." cleanup +if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 +fi echo "# Create desktop-class 4K drive" echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)" @@ -255,14 +283,11 @@ format_plain_fail 2048 format_plain_fail 4096 cleanup +# skip tests using empty passphrase (LUKS1 cipher_null) +if [ ! fips_mode ]; then echo "# Offset check: 512B sector drive" add_device dev_size_mb=16 sector_size=512 num_tgts=1 # |k| expO reqO expected slot offsets -format_null 64 2048 0 8:72:136:200:264:328:392:456 -format_null 64 520 1 -format_null 64 520 8 -format_null 64 640 128 -format_null 64 2048 2048 format_null 128 2048 0 8:136:264:392:520:648:776:904 format_null 128 1032 1 format_null 128 1032 8 @@ -282,11 +307,6 @@ cleanup echo "# Offset check: 4096B sector drive" add_device dev_size_mb=16 sector_size=4096 num_tgts=1 opt_blks=64 -format_null 64 2048 0 8:72:136:200:264:328:392:456 -format_null 64 520 1 -format_null 64 520 8 -format_null 64 640 128 -format_null 64 2048 2048 format_null 128 2048 0 8:136:264:392:520:648:776:904 format_null 128 1032 1 format_null 128 1032 8 @@ -303,18 +323,19 @@ format_null 512 4040 8 format_null 512 4096 128 format_null 512 4096 2048 cleanup +fi echo "# Create enterprise-class 4K drive with fs and LUKS images." # loop device here presents 512 block but images have 4k block # cryptsetup should properly use 4k block on direct-io add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64 for file in $(ls img_fs_*.img.xz) ; do - echo "Format using fs image $file." - xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" - [ ! -d $MNT_DIR ] && mkdir $MNT_DIR - mount $DEV $MNT_DIR || skip "Mounting image is not available." - echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 --key-size 256 $FAST_PBKDF $MNT_DIR/luks.img || fail - echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 --key-size 256 $FAST_PBKDF $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail - umount $MNT_DIR + echo "Format using fs image $file." + xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" + [ ! -d $MNT_DIR ] && mkdir $MNT_DIR + mount $DEV $MNT_DIR || skip "Mounting image is not available." + echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 --key-size 256 $FAST_PBKDF $MNT_DIR/luks.img || fail + echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 --key-size 256 $FAST_PBKDF $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail + umount $MNT_DIR done cleanup diff --git a/tests/align-test2 b/tests/align-test2 index 75d9cf4..33126a4 100755 --- a/tests/align-test2 +++ b/tests/align-test2 @@ -5,23 +5,28 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup DEV="" DEV_STACKED="luks0xbabe" DEV_NAME="dummyalign" +HDR="test_luks2_hdr" MNT_DIR="./mnt_luks" PWD1="93R4P4pIqAH8" PWD2="mymJeD8ivEhE" FAST_PBKDF="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + cleanup() { udevadm settle >/dev/null 2>&1 if [ -d "$MNT_DIR" ] ; then - umount -f $MNT_DIR 2>/dev/null - rmdir $MNT_DIR 2>/dev/null + umount -f $MNT_DIR 2>/dev/null + rmdir $MNT_DIR 2>/dev/null fi [ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 # FIXME scsi_debug sometimes in-use here sleep 1 - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 sleep 1 + rm -f $HDR 2>/dev/null } fail() @@ -37,7 +42,19 @@ skip() { echo "TEST SKIPPED: $1" cleanup - exit 0 + exit 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } function dm_crypt_features() @@ -58,13 +75,13 @@ function dm_crypt_features() [ $VER_MIN -lt 14 ] && return DM_PERF_CPU=1 - if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then + if [ $VER_MIN -ge 17 ]; then DM_SECTOR_SIZE=1 fi } add_device() { - modprobe scsi_debug $@ delay=0 + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "This kernel seems to not support proper scsi_debug module, test skipped." exit 77 @@ -112,7 +129,7 @@ format() # expected [forced] [encryption_sector_size] $CRYPTSETUP close $DEV_NAME || fail fi - ALIGN=$($CRYPTSETUP luksDump $DEV | tee /tmp/last_dump | grep -A1 "0: crypt" | grep "offset:" | cut -d ' ' -f2) + ALIGN=$($CRYPTSETUP luksDump $DEV | grep -A1 "0: crypt" | grep "offset:" | cut -d ' ' -f2) # echo "ALIGN = $ALIGN" [ -z "$ALIGN" ] && fail @@ -120,7 +137,7 @@ format() # expected [forced] [encryption_sector_size] [ $ALIGN -ne $_exp ] && fail "Expected alignment differs: expected $_exp != detected $ALIGN" # test some operation, just in case - echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1 + echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --new-key-slot 1 [ $? -ne 0 ] && fail "Keyslot add failed." $CRYPTSETUP -q luksKillSlot $DEV 1 @@ -155,14 +172,55 @@ format_fail() # expected [forced] [encryption_sector_size] echo "PASSED" } +auto_sector() # expected device header +{ + local _exp=$1 + local _dev=$2 + local _hdr=$2 + local _hdrstr="" + local _hdrmsg="" + + if [ -n "$3" ]; then + _hdrstr="--header $3" + _hdr=$3 + _hdrmsg=" detached header" + fi + + echo -n "Formatting$_hdrmsg using optimal encryption sector size (expecting $_exp)..." + + if [ -z "$DM_SECTOR_SIZE" -a $_exp -ne 512 ]; then + echo "SKIPPED" + return + fi + + echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $_hdrstr $_dev -q >/dev/null 2>&1 || fail + + # check the device can be activated + echo $PWD1 | $CRYPTSETUP luksOpen $_hdrstr $_dev $DEV_NAME || fail + $CRYPTSETUP close $DEV_NAME || fail + + SECTOR=$($CRYPTSETUP luksDump $_hdr | grep -A4 "0: crypt" | grep "sector:" | cut -d ' ' -f2) + + [ -z "$SECTOR" ] && fail + [ $SECTOR -ne $_exp ] && fail "Expected sector size differs: expected $_exp != detected $SECTOR" + + echo "PASSED" +} + +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 fi dm_crypt_features -modprobe --dry-run scsi_debug || exit 77 +modprobe --dry-run scsi_debug >/dev/null 2>&1 || skip "This kernel seems to not support proper scsi_debug module, test skipped." cleanup +if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 +fi add_device dev_size_mb=32 echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q >/dev/null || fail @@ -356,12 +414,36 @@ echo "# Create enterprise-class 4K drive with fs and LUKS images." # cryptsetup should properly use 4k block on direct-io add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64 for file in $(ls img_fs_*.img.xz) ; do - echo "Format using fs image $file." - xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" - [ ! -d $MNT_DIR ] && mkdir $MNT_DIR - mount $DEV $MNT_DIR || skip "Mounting image is not available." - echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --offset 8192 || fail - echo $PWD2 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail - umount $MNT_DIR + echo "Format using fs image $file." + xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" + [ ! -d $MNT_DIR ] && mkdir $MNT_DIR + mount $DEV $MNT_DIR || skip "Mounting image is not available." + echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --offset 8192 || fail + echo $PWD2 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail + umount $MNT_DIR done cleanup + +echo "# Create classic 512B drive" +echo "# (logical_block_size=512, physical_block_size=512, alignment_offset=0)" +add_device dev_size_mb=32 sector_size=512 num_tgts=1 +auto_sector 512 $DEV +auto_sector 512 $DEV $HDR +cleanup +echo "# Create desktop-class 4K drive" +echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)" +add_device dev_size_mb=32 sector_size=512 physblk_exp=3 num_tgts=1 +auto_sector 4096 $DEV +auto_sector 4096 $DEV $HDR +DEV2=$DEV +DEV=/dev/mapper/$DEV_STACKED +dmsetup create $DEV_STACKED --table "0 $((`blockdev --getsz $DEV2`-1)) linear $DEV2 0" +auto_sector 512 $DEV +auto_sector 512 $DEV $HDR +cleanup +echo "# Create enterprise-class 4K drive" +echo "# (logical_block_size=4096, physical_block_size=4096, alignment_offset=0)" +add_device dev_size_mb=32 sector_size=4096 num_tgts=1 opt_blks=64 +auto_sector 4096 $DEV +auto_sector 4096 $DEV $HDR +cleanup diff --git a/tests/all-symbols-test.c b/tests/all-symbols-test.c new file mode 100644 index 0000000..10c7fe2 --- /dev/null +++ b/tests/all-symbols-test.c @@ -0,0 +1,177 @@ +/* + * Test utility checking symbol versions in libcryptsetup. + * + * Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <dlfcn.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define UNUSED(expr) do { (void)(expr); } while (0) + +static int _debug; +static const char *libfile = "libcryptsetup.so.12"; + +#define LOG_MAX_LEN 256 + +#define LOG_DEBUG 1 +#define LOG_NORMAL 2 +#define LOG_ERROR 3 + +__attribute__((format(printf, 2, 3))) +static void test_logf(int level, const char *format, ...) +{ + va_list argp; + char target[LOG_MAX_LEN + 2]; + int len; + + va_start(argp, format); + + len = vsnprintf(&target[0], LOG_MAX_LEN, format, argp); + if (len > 0 && len < LOG_MAX_LEN) { + switch (level) { + case LOG_DEBUG: + if (!_debug) + break; + /* fall through */ + case LOG_NORMAL: + fprintf(stdout, "%s", target); + break; + case LOG_ERROR: + fflush(stdout); + strcat(target, "\n"); + fprintf(stderr, "%s", target); + } + } + + va_end(argp); +} + +#define log_dbg(x...) test_logf(LOG_DEBUG, x) +#define log_std(x...) test_logf(LOG_NORMAL, x) +#define log_err(x...) test_logf(LOG_ERROR, x) + +static int check_dlvsym(void *h, const char *symbol, const char *version) +{ +#ifdef HAVE_DLVSYM + void *sym; + char *err; + + log_dbg("Checking %s@%s...", symbol, version); + sym = dlvsym(h, symbol, version); + UNUSED(sym); + err = dlerror(); + + if (err) { + log_err("%s.", err); + return 1; + } + + log_dbg("OK\n"); +#endif + return 0; +} + +static int check_dlsym(void *h, const char *symbol) +{ + void *sym; + char *err; + + log_dbg("Checking %s...", symbol); + sym = dlsym(h, symbol); + UNUSED(sym); + err = dlerror(); + + if (err) { + log_err("%s", err); + return 1; + } + + log_dbg("OK\n"); + return 0; +} + +static int check_all_symbols(void *h) +{ + unsigned scount = 0; + +#define CHECK_SYMBOL(SYM, VER) \ +do { \ + if (check_dlvsym(h, #SYM, #VER)) \ + return 1; \ + if (check_dlsym(h, #SYM)) \ + return 1; \ + scount++; \ +} while (0); + +#include "test-symbols-list.h" +#undef CHECK_SYMBOL + + if (!scount) { + log_err("test-symbols-list.h file is probably empty."); + return 1; + } + + log_std("Performed %u symbol checks in total.\n", scount); + + return 0; +} + +static void usage(const char *app) +{ + log_std("usage:\n\t%s [-v|--verbose|--debug] [optional path to library so file]\n", app); + + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + int i, r; + void *h; + + for (i = 1; i < argc; i++) { + if (*argv[i] != '-') + libfile = argv[i]; + else if (!strcmp("-v", argv[i]) || !strcmp("--verbose", argv[i]) || + !strcmp("--debug", argv[i])) + _debug = 1; + else if (!strcmp("-h", argv[i]) || !strcmp("--help", argv[i])) + usage(argv[0]); + } + + log_std("Checking dlopen(%s)...", libfile); + + h = dlopen(libfile, RTLD_NOW); + if (!h) { + log_err("dlopen(): %s.", dlerror()); + return EXIT_FAILURE; + } + dlerror(); + log_std("OK\n"); + + r = check_all_symbols(h); + + if (dlclose(h)) { + log_err("Failed to dlclose %s: %s.", libfile, dlerror()); + return EXIT_FAILURE; + } + + return r ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/api-test-2.c b/tests/api-test-2.c index c0bfc9a..824ae65 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-2021 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2021 Milan Broz - * Copyright (C) 2016-2021 Ondrej Kozina + * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2023 Milan Broz + * Copyright (C) 2016-2023 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -41,11 +41,9 @@ typedef int32_t key_serial_t; #endif #include "api_test.h" -#include "luks.h" +#include "luks1/luks.h" #include "libcryptsetup.h" -#define DMDIR "/dev/mapper/" - #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b" #define DEVICE_EMPTY_name "crypt_zero" #define DEVICE_EMPTY DMDIR DEVICE_EMPTY_name @@ -76,8 +74,8 @@ typedef int32_t key_serial_t; #define KEYFILE2 "key2.file" #define KEY2 "0123456789abcdef" -#define PASSPHRASE "blabla" -#define PASSPHRASE1 "albalb" +#define PASSPHRASE "blablabl" +#define PASSPHRASE1 "albalbal" #define DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc" @@ -109,25 +107,15 @@ typedef int32_t key_serial_t; #define CONV_L2_512_DET_FULL "l2_512b_det_full" #define CONV_L1_256_LEGACY "l1_256b_legacy_offset" #define CONV_L1_256_UNMOVABLE "l1_256b_unmovable" -#define PASS0 "aaa" -#define PASS1 "hhh" -#define PASS2 "ccc" -#define PASS3 "ddd" -#define PASS4 "eee" -#define PASS5 "fff" -#define PASS6 "ggg" -#define PASS7 "bbb" -#define PASS8 "iii" - -/* Allow to run without config.h */ -#ifndef DEFAULT_LUKS1_HASH - #define DEFAULT_LUKS1_HASH "sha256" - #define DEFAULT_LUKS1_ITER_TIME 2000 - #define DEFAULT_LUKS2_ITER_TIME 2000 - #define DEFAULT_LUKS2_MEMORY_KB 1048576 - #define DEFAULT_LUKS2_PARALLEL_THREADS 4 - #define DEFAULT_LUKS2_PBKDF "argon2i" -#endif +#define PASS0 "aaablabl" +#define PASS1 "hhhblabl" +#define PASS2 "cccblabl" +#define PASS3 "dddblabl" +#define PASS4 "eeeblabl" +#define PASS5 "fffblabl" +#define PASS6 "gggblabl" +#define PASS7 "bbbblabl" +#define PASS8 "iiiblabl" static int _fips_mode = 0; @@ -145,6 +133,26 @@ unsigned int test_progress_steps; struct crypt_device *cd = NULL, *cd2 = NULL; +static const char *default_luks1_hash = NULL; +static uint32_t default_luks1_iter_time = 0; + +static const char *default_luks2_pbkdf = NULL; +static uint32_t default_luks2_iter_time = 0; +static uint32_t default_luks2_memory_kb = 0; +static uint32_t default_luks2_parallel_threads = 0; + +static struct crypt_pbkdf_type min_pbkdf2 = { + .type = "pbkdf2", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK +}, min_argon2 = { + .type = "argon2id", + .iterations = 4, + .max_memory_kb = 32, + .parallel_threads = 1, + .flags = CRYPT_PBKDF_NO_BENCHMARK +}; + // Helpers static unsigned cpus_online(void) @@ -167,14 +175,14 @@ static uint32_t adjusted_pbkdf_memory(void) uint64_t memory_kb; if (pagesize <= 0 || pages <= 0) - return DEFAULT_LUKS2_MEMORY_KB; + return default_luks2_memory_kb; memory_kb = pagesize / 1024 * pages / 2; - if (memory_kb < DEFAULT_LUKS2_MEMORY_KB) + if (memory_kb < default_luks2_memory_kb) return (uint32_t)memory_kb; - return DEFAULT_LUKS2_MEMORY_KB; + return default_luks2_memory_kb; } static unsigned _min(unsigned a, unsigned b) @@ -191,6 +199,11 @@ static int get_luks2_offsets(int metadata_device, struct crypt_device *cd = NULL; static uint64_t default_header_size = 0; + if (r_header_size) + *r_header_size = 0; + if (r_payload_offset) + *r_payload_offset = 0; + if (!default_header_size) { if (crypt_init(&cd, THE_LOOP_DEV)) return -EINVAL; @@ -225,6 +238,28 @@ static int get_luks2_offsets(int metadata_device, return 0; } +static bool get_luks_pbkdf_defaults(void) +{ + const struct crypt_pbkdf_type *pbkdf_defaults = crypt_get_pbkdf_default(CRYPT_LUKS1); + + if (!pbkdf_defaults) + return false; + + default_luks1_hash = pbkdf_defaults->hash; + default_luks1_iter_time = pbkdf_defaults->time_ms; + + pbkdf_defaults = crypt_get_pbkdf_default(CRYPT_LUKS2); + if (!pbkdf_defaults) + return false; + + default_luks2_pbkdf = pbkdf_defaults->type; + default_luks2_iter_time = pbkdf_defaults->time_ms; + default_luks2_memory_kb = pbkdf_defaults->max_memory_kb; + default_luks2_parallel_threads = pbkdf_defaults->parallel_threads; + + return true; +} + static void _remove_keyfiles(void) { remove(KEYFILE1); @@ -344,13 +379,17 @@ static int _setup(void) char cmd[128]; test_loop_file = strdup(THE_LFILE_TEMPLATE); + if (!test_loop_file) + return 1; + if ((fd=mkstemp(test_loop_file)) == -1) { printf("cannot create temporary file with template %s\n", test_loop_file); return 1; } close(fd); - snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", - test_loop_file, SECTOR_SIZE, TST_LOOP_FILE_SIZE); + if (snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", + test_loop_file, TST_SECTOR_SIZE, TST_LOOP_FILE_SIZE) < 0) + return 1; if (_system(cmd, 1)) return 1; @@ -358,19 +397,26 @@ static int _setup(void) close(fd); tmp_file_1 = strdup(THE_LFILE_TEMPLATE); + if (!tmp_file_1) + return 1; + if ((fd=mkstemp(tmp_file_1)) == -1) { printf("cannot create temporary file with template %s\n", tmp_file_1); return 1; } close(fd); - snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", - tmp_file_1, SECTOR_SIZE, 10); + if (snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", + tmp_file_1, TST_SECTOR_SIZE, 10) < 0) + return 1; if (_system(cmd, 1)) return 1; _system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"", 1); _system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1); + if (t_set_readahead(DEVICE_ERROR, 0)) + printf("cannot set read ahead on device %s\n", DEVICE_ERROR); + _system(" [ ! -e " IMAGE1 " ] && xz -dk " IMAGE1 ".xz", 1); fd = loop_attach(&DEVICE_1, IMAGE1, 0, 0, &ro); close(fd); @@ -383,11 +429,11 @@ static int _setup(void) _system("dd if=/dev/zero of=" IMAGE_EMPTY_SMALL_2 " bs=512 count=2050 2>/dev/null", 1); - _system(" [ ! -e " NO_REQS_LUKS2_HEADER " ] && xz -dk " NO_REQS_LUKS2_HEADER ".xz", 1); + _system(" [ ! -e " NO_REQS_LUKS2_HEADER " ] && tar xJf " REQS_LUKS2_HEADER ".tar.xz", 1); fd = loop_attach(&DEVICE_4, NO_REQS_LUKS2_HEADER, 0, 0, &ro); close(fd); - _system(" [ ! -e " REQS_LUKS2_HEADER " ] && xz -dk " REQS_LUKS2_HEADER ".xz", 1); + _system(" [ ! -e " REQS_LUKS2_HEADER " ] && tar xJf " REQS_LUKS2_HEADER ".tar.xz", 1); fd = loop_attach(&DEVICE_5, REQS_LUKS2_HEADER, 0, 0, &ro); close(fd); @@ -398,13 +444,13 @@ static int _setup(void) _system(" [ ! -d " CONV_DIR " ] && tar xJf " CONV_DIR ".tar.xz 2>/dev/null", 1); - if (_system("modprobe dm-crypt", 1)) + if (_system("modprobe dm-crypt >/dev/null 2>&1", 1)) return 1; if (t_dm_check_versions()) return 1; - _system("rmmod dm-crypt", 0); + _system("rmmod dm-crypt >/dev/null 2>&1", 0); _fips_mode = fips_mode(); if (_debug) @@ -413,9 +459,25 @@ static int _setup(void) /* Use default log callback */ crypt_set_log_callback(NULL, &global_log_callback, NULL); + if (!get_luks_pbkdf_defaults()) + return 1; + + min_pbkdf2.hash = min_argon2.hash = default_luks1_hash; + return 0; } +static int set_fast_pbkdf(struct crypt_device *cd) +{ + const struct crypt_pbkdf_type *pbkdf = &min_argon2; + + /* Cannot use Argon2 in FIPS */ + if (_fips_mode) + pbkdf = &min_pbkdf2; + + return crypt_set_pbkdf_type(cd, pbkdf); +} + #ifdef KERNEL_KEYRING static key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t keyring) { @@ -461,11 +523,11 @@ static int _drop_keyring_key(struct crypt_device *cd, int segment) } #endif -static int test_open(struct crypt_device *cd, - int token, - char **buffer, - size_t *buffer_len, - void *usrptr) +static int test_open(struct crypt_device *cd __attribute__((unused)), + int token __attribute__((unused)), + char **buffer, + size_t *buffer_len, + void *usrptr) { const char *str = (const char *)usrptr; @@ -477,7 +539,7 @@ static int test_open(struct crypt_device *cd, return 0; } -static int test_validate(struct crypt_device *cd, const char *json) +static int test_validate(struct crypt_device *cd __attribute__((unused)), const char *json) { return (strstr(json, "magic_string") == NULL); } @@ -542,12 +604,6 @@ static void SuspendDevice(void) 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)); @@ -617,7 +673,7 @@ static void SuspendDevice(void) /* Resume device with cipher_null */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(set_fast_pbkdf(cd)); 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)); @@ -653,10 +709,10 @@ static void AddDeviceLuks2(void) }; char key[128], key2[128], key3[128]; - const char *passphrase = "blabla", *passphrase2 = "nsdkFI&Y#.sd"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - const char *mk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; - size_t key_size = strlen(mk_hex) / 2; + const char *tmp_buf, *passphrase = PASSPHRASE, *passphrase2 = "nsdkFI&Y#.sd"; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset, r_header_size, r_size_1; @@ -668,8 +724,8 @@ static void AddDeviceLuks2(void) pbkdf.max_memory_kb = 0; } - crypt_decode_key(key, mk_hex, key_size); - crypt_decode_key(key3, mk_hex2, key_size); + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key3, vk_hex2, key_size); // init test devices OK_(get_luks2_offsets(0, 0, 0, &r_header_size, &r_payload_offset)); @@ -685,6 +741,7 @@ static void AddDeviceLuks2(void) // test payload_offset = 0 for encrypted device with external header device OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); EQ_(crypt_get_data_offset(cd), 0); CRYPT_FREE(cd); @@ -694,6 +751,7 @@ static void AddDeviceLuks2(void) // test payload_offset = 0. format() should look up alignment offset from device topology OK_(crypt_init(&cd, DEVICE_2)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); OK_(!(crypt_get_data_offset(cd) > 0)); CRYPT_FREE(cd); @@ -701,6 +759,7 @@ static void AddDeviceLuks2(void) // set_data_offset has priority, alignment must be 0 or must be compatible params.data_alignment = 0; OK_(crypt_init(&cd, DEVICE_2)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_set_data_offset(cd, OFFSET_8M)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); EQ_(crypt_get_data_offset(cd), OFFSET_8M); @@ -715,6 +774,7 @@ static void AddDeviceLuks2(void) params.data_alignment = OFFSET_4M; OK_(crypt_init(&cd, DEVICE_2)); + OK_(set_fast_pbkdf(cd)); FAIL_(crypt_set_data_offset(cd, OFFSET_2M + 1), "Not aligned to 4096"); // must be aligned to 4k OK_(crypt_set_data_offset(cd, OFFSET_2M)); FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Alignment not compatible"); @@ -734,23 +794,26 @@ static void AddDeviceLuks2(void) // 1 sector less than required OK_(crypt_init(&cd, DMDIR L_DEVICE_WRONG)); + OK_(set_fast_pbkdf(cd)); FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Device too small"); CRYPT_FREE(cd); // 0 sectors for encrypted area OK_(crypt_init(&cd, DMDIR L_DEVICE_0S)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0), "Encrypted area too small"); CRYPT_FREE(cd); // 1 sector for encrypted area OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); + OK_(set_fast_pbkdf(cd)); 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)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(t_device_size(DMDIR CDEVICE_1, &r_size_1)); - EQ_(r_size_1, SECTOR_SIZE); + EQ_(r_size_1, TST_SECTOR_SIZE); OK_(crypt_deactivate(cd, CDEVICE_1)); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); // restrict format only to empty context @@ -769,6 +832,7 @@ static void AddDeviceLuks2(void) // generate keyslot material at the end of luks header OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); EQ_((int)key_size, crypt_get_volume_key_size(cd)); EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), 7); @@ -787,6 +851,7 @@ static void AddDeviceLuks2(void) CRYPT_FREE(cd); OK_(crypt_init_by_name_and_header(&cd, CDEVICE_1, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Context is already formatted"); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); CRYPT_FREE(cd); @@ -805,12 +870,15 @@ static void AddDeviceLuks2(void) // test uuid mismatch and _init_by_name_and_header OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); + EQ_(0, crypt_header_is_detached(cd)); CRYPT_FREE(cd); params.data_alignment = 0; params.data_device = DEVICE_2; OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); CRYPT_FREE(cd); // there we've got uuid mismatch @@ -821,11 +889,13 @@ static void AddDeviceLuks2(void) FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0), "Device is active"); EQ_(crypt_status(cd, CDEVICE_2), CRYPT_INACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(crypt_header_is_detached(cd), 1); CRYPT_FREE(cd); params.data_device = NULL; OK_(crypt_init(&cd, DEVICE_2)); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); // even with no keyslots defined it can be activated by volume key @@ -841,7 +911,6 @@ static void AddDeviceLuks2(void) GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_2)); - crypt_set_iteration_time(cd, 1); EQ_(1, crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, KEY1, strlen(KEY1))); OK_(prepare_keyfile(KEYFILE1, KEY1, strlen(KEY1))); OK_(prepare_keyfile(KEYFILE2, KEY2, strlen(KEY2))); @@ -868,7 +937,7 @@ static void AddDeviceLuks2(void) key[1] = ~key[1]; FAIL_(crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase)), "key mismatch"); key[1] = ~key[1]; - EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase, strlen(passphrase))); + EQ_(6, crypt_keyslot_add_by_volume_key(cd, 6, key, key_size, passphrase2, strlen(passphrase2))); EQ_(CRYPT_SLOT_ACTIVE, crypt_keyslot_status(cd, 6)); FAIL_(crypt_keyslot_destroy(cd, 8), "invalid keyslot"); @@ -878,6 +947,8 @@ static void AddDeviceLuks2(void) EQ_(CRYPT_SLOT_INACTIVE, crypt_keyslot_status(cd, 7)); EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6)); + EQ_(6, crypt_keyslot_change_by_passphrase(cd, 6, CRYPT_ANY_SLOT, passphrase2, strlen(passphrase2), passphrase, strlen(passphrase))); + EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 6)); EQ_(7, crypt_keyslot_change_by_passphrase(cd, 6, 7, passphrase, strlen(passphrase), passphrase2, strlen(passphrase2))); EQ_(CRYPT_SLOT_ACTIVE_LAST, crypt_keyslot_status(cd, 7)); EQ_(7, crypt_activate_by_passphrase(cd, NULL, 7, passphrase2, strlen(passphrase2), 0)); @@ -898,6 +969,13 @@ static void AddDeviceLuks2(void) OK_(!(global_lines != 0)); reset_log(); + FAIL_(crypt_dump_json(cd, NULL, 42), "flags be used later"); + OK_(crypt_dump_json(cd, NULL, 0)); + OK_(!(global_lines != 0)); + reset_log(); + OK_(crypt_dump_json(cd, &tmp_buf, 0)); + OK_(!(tmp_buf && strlen(tmp_buf) != 0)); + FAIL_(crypt_set_uuid(cd, "blah"), "wrong UUID format"); OK_(crypt_set_uuid(cd, DEVICE_TEST_UUID)); OK_(strcmp(DEVICE_TEST_UUID, crypt_get_uuid(cd))); @@ -920,13 +998,13 @@ static void AddDeviceLuks2(void) OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, NULL)); CRYPT_FREE(cd); OK_(crypt_init(&cd, DEVICE_2)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, key_size, PASSPHRASE, strlen(PASSPHRASE)), 0); CRYPT_FREE(cd); OK_(crypt_init(&cd, DEVICE_2)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, key_size, NULL)); FAIL_(crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, key, key_size, PASSPHRASE, strlen(PASSPHRASE)), "VK doesn't match any digest"); FAIL_(crypt_keyslot_add_by_volume_key(cd, 1, key, key_size, PASSPHRASE, strlen(PASSPHRASE)), "VK doesn't match any digest"); @@ -934,7 +1012,7 @@ static void AddDeviceLuks2(void) OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 3, NULL, key_size, PASSPHRASE, strlen(PASSPHRASE)), 3); FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_1, key3, key_size, 0), "VK doesn't match any digest assigned to segment 0"); @@ -945,7 +1023,7 @@ static void AddDeviceLuks2(void) * volume key size is unknown (no active keyslots). */ OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, key_size, PASSPHRASE, strlen(PASSPHRASE)), 0); /* drop context copy of volume key */ @@ -954,6 +1032,7 @@ static void AddDeviceLuks2(void) OK_(crypt_load(cd, CRYPT_LUKS, NULL)); EQ_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, PASSPHRASE, strlen(PASSPHRASE)), 0); OK_(crypt_keyslot_destroy(cd, 0)); + OK_(set_fast_pbkdf(cd)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, key, key_size, PASSPHRASE, strlen(PASSPHRASE)), 0); CRYPT_FREE(cd); @@ -977,9 +1056,8 @@ static void Luks2MetadataSize(void) }; char key[128], tmp[128]; - const char *passphrase = "blabla"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_header_size, default_mdata_size, default_keyslots_size, mdata_size, @@ -993,7 +1071,7 @@ static void Luks2MetadataSize(void) pbkdf.iterations = 1000; } - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); // init test devices OK_(get_luks2_offsets(0, 0, 0, &r_header_size, NULL)); @@ -1024,7 +1102,7 @@ static void Luks2MetadataSize(void) OK_(crypt_init(&cd, DMDIR H_DEVICE)); OK_(crypt_set_metadata_size(cd, 0x080000, 0x080000)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); - EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, passphrase, strlen(passphrase)), 7); + EQ_(crypt_keyslot_add_by_volume_key(cd, 7, key, key_size, PASSPHRASE, strlen(PASSPHRASE)), 7); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR H_DEVICE)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); @@ -1119,9 +1197,9 @@ static void UseTempVolumes(void) // Dirty checks: device without UUID // we should be able to remove it but not manipulate with it - snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" + GE_(snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 " - "%s 2048\"", CDEVICE_2, DEVICE_2); + "%s 2048\"", CDEVICE_2, DEVICE_2), 0); _system(tmp, 1); OK_(crypt_init_by_name(&cd, CDEVICE_2)); OK_(crypt_deactivate(cd, CDEVICE_2)); @@ -1129,10 +1207,10 @@ static void UseTempVolumes(void) CRYPT_FREE(cd); // Dirty checks: device with UUID but LUKS header key fingerprint must fail) - snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" + GE_(snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 " "%s 2048\" -u CRYPT-LUKS2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-ctest1", - CDEVICE_2, DEVICE_2); + CDEVICE_2, DEVICE_2), 0); _system(tmp, 1); OK_(crypt_init_by_name(&cd, CDEVICE_2)); OK_(crypt_deactivate(cd, CDEVICE_2)); @@ -1162,7 +1240,7 @@ static void Luks2HeaderRestore(void) .sector_size = 512 }; struct crypt_params_plain pl_params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 @@ -1172,8 +1250,8 @@ static void Luks2HeaderRestore(void) }; uint32_t flags = 0; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "ccadd99b16cd3d200c22d6db45d8b6630ef3d936767127347ec8a76ab992c2ea"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset; @@ -1185,7 +1263,7 @@ static void Luks2HeaderRestore(void) pbkdf.max_memory_kb = 0; } - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); 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)); @@ -1224,7 +1302,7 @@ static void Luks2HeaderRestore(void) // do not allow restore over LUKS1 header on device OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, NULL, 32, &luks1)); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); @@ -1267,15 +1345,15 @@ static void Luks2HeaderLoad(void) .sector_size = 512 }; struct crypt_params_plain pl_params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 }; char key[128], cmd[256]; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset, r_header_size, img_size; @@ -1287,7 +1365,7 @@ static void Luks2HeaderLoad(void) pbkdf.max_memory_kb = 0; } - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); // hardcoded values for existing image IMAGE1 img_size = 8192; @@ -1298,7 +1376,8 @@ static void Luks2HeaderLoad(void) // prepared header on a device too small to contain header and payload //OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, r_payload_offset - 1)); OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, img_size - 1)); - snprintf(cmd, sizeof(cmd), "dd if=" IMAGE1 " of=" DMDIR H_DEVICE_WRONG " bs=%" PRIu32 " count=%" PRIu64 " 2>/dev/null", params.sector_size, img_size - 1); + GE_(snprintf(cmd, sizeof(cmd), "dd if=" IMAGE1 " of=" DMDIR H_DEVICE_WRONG " bs=%" PRIu32 + " count=%" PRIu64 " 2>/dev/null", params.sector_size, img_size - 1), 0); OK_(_system(cmd, 1)); // some device OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000)); @@ -1321,6 +1400,7 @@ static void Luks2HeaderLoad(void) 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)); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // repeat with init with two devices @@ -1331,6 +1411,7 @@ static void Luks2HeaderLoad(void) OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(!crypt_get_metadata_device_name(cd)); EQ_(strcmp(DMDIR H_DEVICE, crypt_get_metadata_device_name(cd)), 0); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // bad header: device too small (payloadOffset > device_size) @@ -1404,8 +1485,8 @@ static void Luks2HeaderBackup(void) char key[128]; int fd, ro = O_RDONLY; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset; @@ -1419,7 +1500,7 @@ static void Luks2HeaderBackup(void) pbkdf.max_memory_kb = 0; } - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); 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)); @@ -1441,6 +1522,7 @@ static void Luks2HeaderBackup(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(0, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // exercise luksOpen using backup header in file @@ -1450,6 +1532,7 @@ static void Luks2HeaderBackup(void) EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); OK_(crypt_init(&cd, BACKUP_FILE)); @@ -1499,10 +1582,10 @@ static void ResizeDeviceLuks2(void) }; char key[128]; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; - const char *cipher = "aes"; - const char *cipher_mode = "cbc-essiv:sha256"; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; + const char *cipher = "aes", *capi_cipher = "capi:cbc(aes)"; + const char *cipher_mode = "cbc-essiv:sha256", *capi_cipher_mode = "essiv:sha256"; uint64_t r_payload_offset, r_header_size, r_size; /* Cannot use Argon2 in FIPS */ @@ -1512,7 +1595,7 @@ static void ResizeDeviceLuks2(void) pbkdf.max_memory_kb = 0; } - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); // prepare env OK_(get_luks2_offsets(0, params.data_alignment, 0, NULL, &r_payload_offset)); @@ -1531,15 +1614,15 @@ static void ResizeDeviceLuks2(void) OK_(crypt_resize(cd, CDEVICE_1, 0)); OK_(crypt_resize(cd, CDEVICE_1, 42)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(42, r_size >> SECTOR_SHIFT); + EQ_(42, r_size >> TST_SECTOR_SHIFT); OK_(crypt_resize(cd, CDEVICE_1, 0)); // autodetect encrypted device area size OK_(crypt_resize(cd, CDEVICE_1, 0)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(1000, r_size >> SECTOR_SHIFT); + EQ_(1000, r_size >> TST_SECTOR_SHIFT); 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_(1000, r_size >> TST_SECTOR_SHIFT); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1552,14 +1635,14 @@ static void ResizeDeviceLuks2(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); OK_(crypt_resize(cd, CDEVICE_1, 666)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(666, r_size >> SECTOR_SHIFT); + EQ_(666, r_size >> TST_SECTOR_SHIFT); // autodetect encrypted device size OK_(crypt_resize(cd, CDEVICE_1, 0)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(1000, r_size >> SECTOR_SHIFT); + EQ_(1000, r_size >> TST_SECTOR_SHIFT); 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_(1000, r_size >> TST_SECTOR_SHIFT); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1592,7 +1675,7 @@ static void ResizeDeviceLuks2(void) OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, t_dm_crypt_keyring_support() ? CRYPT_ACTIVATE_KEYRING_KEY : 0)); OK_(crypt_resize(cd, CDEVICE_1, 43)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(43, r_size >> SECTOR_SHIFT); + EQ_(43, r_size >> TST_SECTOR_SHIFT); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); @@ -1627,7 +1710,7 @@ static void ResizeDeviceLuks2(void) CRYPT_FREE(cd2); OK_(crypt_init(&cd2, DMDIR L_DEVICE_WRONG)); - crypt_set_iteration_time(cd2, 1); + OK_(crypt_set_pbkdf_type(cd2, &min_pbkdf2)); OK_(crypt_format(cd2, CRYPT_LUKS1, cipher, cipher_mode, crypt_get_uuid(cd), key, key_size, NULL)); OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, key_size, 0)); FAIL_(crypt_resize(cd2, CDEVICE_1, 1), "Device got resized by wrong device context."); @@ -1644,6 +1727,18 @@ static void ResizeDeviceLuks2(void) OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); + if (t_dm_capi_string_supported()) { + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_format(cd, CRYPT_LUKS2, capi_cipher, capi_cipher_mode, NULL, key, key_size, NULL)); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); + OK_(crypt_resize(cd, CDEVICE_1, 8)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(8, r_size >> TST_SECTOR_SHIFT); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + } + _cleanup_dmdevices(); } @@ -1660,7 +1755,7 @@ static void TokenActivationByKeyring(void) .key_description = KEY_DESC_TEST0 }, params2 = { .key_description = KEY_DESC_TEST1 - }; + }, params_invalid = {}; uint64_t r_payload_offset; if (!t_dm_crypt_keyring_support()) { @@ -1676,9 +1771,10 @@ static void TokenActivationByKeyring(void) // prepare the device OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); + FAIL_(crypt_token_luks2_keyring_set(cd, CRYPT_ANY_TOKEN, ¶ms_invalid), "Invalid key description property."); EQ_(crypt_token_luks2_keyring_set(cd, 3, ¶ms), 3); EQ_(crypt_token_assign_keyslot(cd, 3, 0), 3); CRYPT_FREE(cd); @@ -1727,7 +1823,7 @@ static void TokenActivationByKeyring(void) EQ_(crypt_token_assign_keyslot(cd, 0, 0), 0); EQ_(crypt_token_luks2_keyring_set(cd, 1, ¶ms2), 1); FAIL_(crypt_token_assign_keyslot(cd, 1, 1), "Keyslot 1 doesn't exist"); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); EQ_(crypt_keyslot_add_by_passphrase(cd, 1, PASSPHRASE, strlen(PASSPHRASE), PASSPHRASE1, strlen(PASSPHRASE1)), 1); EQ_(crypt_token_assign_keyslot(cd, 1, 1), 1); CRYPT_FREE(cd); @@ -1765,7 +1861,7 @@ static void TokenActivationByKeyring(void) OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); OK_(crypt_keyslot_destroy(cd, 0)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); EQ_(crypt_keyslot_add_by_passphrase(cd, 0, PASSPHRASE1, strlen(PASSPHRASE1), PASSPHRASE1, strlen(PASSPHRASE1)), 0); CRYPT_FREE(cd); @@ -1780,7 +1876,7 @@ static void TokenActivationByKeyring(void) // 1st token being invalid (missing key in keyring) // 2nd token can activate keyslot 1 after failing to do so w/ keyslot 0 (wrong pass) OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1)), 1); @@ -1830,12 +1926,13 @@ static void Tokens(void) "\"key_description\":" y ", \"some_field\":\"some_value\"}" - int ks; + int ks, token_max; const char *dummy; const char *cipher = "aes"; const char *cipher_mode = "xts-plain64"; char passptr[] = PASSPHRASE; char passptr1[] = PASSPHRASE1; + struct crypt_active_device cad; static const crypt_token_handler th = { .name = "test_token", @@ -1868,7 +1965,7 @@ static void Tokens(void) // basic token API tests OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); EQ_(crypt_token_status(cd, -1, NULL), CRYPT_TOKEN_INVALID); EQ_(crypt_token_status(cd, 32, NULL), CRYPT_TOKEN_INVALID); @@ -1981,9 +2078,84 @@ static void Tokens(void) 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); + + // test token activation respects keyslot priorities + OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); + EQ_(crypt_keyslot_add_by_key(cd, 3, NULL, 32, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 3); + EQ_(crypt_keyslot_add_by_volume_key(cd, 5, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 5); + EQ_(crypt_keyslot_add_by_volume_key(cd, 8, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1)), 8); + EQ_(crypt_keyslot_add_by_volume_key(cd, 12, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 12); + EQ_(crypt_keyslot_add_by_volume_key(cd, 21, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 21); + EQ_(crypt_keyslot_add_by_volume_key(cd, 31, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 31); + + OK_(crypt_keyslot_set_priority(cd, 0, CRYPT_SLOT_PRIORITY_IGNORE)); + OK_(crypt_keyslot_set_priority(cd, 3, CRYPT_SLOT_PRIORITY_PREFER)); + OK_(crypt_keyslot_set_priority(cd, 8, CRYPT_SLOT_PRIORITY_PREFER)); + OK_(crypt_keyslot_set_priority(cd, 12,CRYPT_SLOT_PRIORITY_PREFER)); + + // expected unusable with CRYPT_ANY_TOKEN + EQ_(crypt_token_json_set(cd, 1, TEST_TOKEN_JSON("\"0\", \"3\"")), 1); + + // expected unusable (-EPERM) + EQ_(crypt_token_json_set(cd, 5, TEST_TOKEN_JSON("\"8\"")), 5); + + // expected unusable (-EPERM) + EQ_(crypt_token_json_set(cd, 4, TEST_TOKEN_JSON("\"8\", \"3\"")), 4); + // expected unusable (-ENOENT) + EQ_(crypt_token_json_set(cd, 6, TEST_TOKEN_JSON("\"3\"")), 6); + + // expected unusable (-ENOENT) + EQ_(crypt_token_json_set(cd, 11, TEST_TOKEN_JSON("")), 11); + + token_max = crypt_token_max(CRYPT_LUKS2) - 1; + GE_(token_max, 0); + + // expected to be used first with CRYPT_ANY_TOKEN (unlocks with high priority ks 12) + EQ_(crypt_token_json_set(cd, token_max, TEST_TOKEN_JSON("\"12\", \"0\", \"3\"")), token_max); + + // expected usable with CRYPT_ANY_TOKEN + EQ_(crypt_token_json_set(cd, 8, TEST_TOKEN_JSON("\"5\", \"0\", \"3\"")), 8); + + // of all tokens keyslot 12 has highest priority now + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", CRYPT_ANY_TOKEN, NULL, 0, passptr, 0), 12); + EQ_(crypt_activate_by_token_pin(cd, CDEVICE_1, "test_token", CRYPT_ANY_TOKEN, NULL, 0, passptr, 0), 12); + OK_(crypt_deactivate(cd, CDEVICE_1)); + + // with explicit token priority ignore may be used + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 1, NULL, 0, passptr, 0), 0); + EQ_(crypt_activate_by_token_pin(cd, CDEVICE_1, "test_token", 1, NULL, 0, passptr, 0), 0); + OK_(crypt_deactivate(cd, CDEVICE_1)); + + EQ_(crypt_token_json_set(cd, token_max, NULL), token_max); + + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", CRYPT_ANY_TOKEN, NULL, 0, passptr, 0), 5); + + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 5, NULL, 0, passptr, 0), -EPERM); + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 4, NULL, 0, passptr, 0), -EPERM); + + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 6, NULL, 0, passptr, 0), -ENOENT); + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 6, NULL, 0, passptr, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), 3); + + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 11, NULL, 0, passptr, 0), -ENOENT); + EQ_(crypt_activate_by_token_pin(cd, NULL, "test_token", 11, NULL, 0, passptr, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY), -ENOENT); + + // test crypt_resume_by_token_pin + EQ_(crypt_activate_by_token_pin(cd, CDEVICE_1, "test_token", CRYPT_ANY_TOKEN, NULL, 0, passptr, 0), 5); + OK_(crypt_suspend(cd, CDEVICE_1)); + EQ_(crypt_resume_by_token_pin(cd, CDEVICE_1, "test_token", CRYPT_ANY_TOKEN, NULL, 0, passptr), 5); + 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); + EQ_(crypt_token_max(CRYPT_LUKS2), 32); + FAIL_(crypt_token_max(CRYPT_LUKS1), "No token support in LUKS1"); + FAIL_(crypt_token_max(NULL), "No LUKS format specified"); _cleanup_dmdevices(); } @@ -2000,7 +2172,7 @@ static void LuksConvert(void) .parallel_threads = 1 }, pbkdf2 = { .type = CRYPT_KDF_PBKDF2, - .hash = "sha1", + .hash = "sha256", .time_ms = 1 }; @@ -2019,7 +2191,7 @@ static void LuksConvert(void) // prepare the device OK_(crypt_init(&cd, DEVICE_1)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, NULL, 32, NULL)); offset = crypt_get_data_offset(cd); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); @@ -2495,8 +2667,7 @@ static void LuksConvert(void) // detached LUKS1 header upconversion OK_(create_dmdevice_over_loop(H_DEVICE, 2050)); // default LUKS1 header should fit there OK_(crypt_init(&cd, DMDIR H_DEVICE)); - crypt_set_iteration_time(cd, 1); - //OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", NULL, NULL, 32, &luks1)); EQ_(crypt_keyslot_add_by_volume_key(cd, 7, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 7); FAIL_(crypt_convert(cd, CRYPT_LUKS2, NULL), "Unable to move keyslots. Not enough space."); @@ -2504,8 +2675,7 @@ static void LuksConvert(void) // 2050 sectors, empty file OK_(crypt_init(&cd, IMAGE_EMPTY_SMALL_2)); - //OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); - crypt_set_iteration_time(cd, 1); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); OK_(crypt_format(cd, CRYPT_LUKS1, "aes", "xts-plain64", NULL, NULL, 32, &luks1)); EQ_(crypt_get_data_offset(cd), 0); EQ_(crypt_keyslot_add_by_volume_key(cd, 7, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 7); @@ -2522,20 +2692,20 @@ static void Pbkdf(void) const char *cipher = "aes", *mode="xts-plain64"; struct crypt_pbkdf_type argon2 = { .type = CRYPT_KDF_ARGON2I, - .hash = DEFAULT_LUKS1_HASH, + .hash = default_luks1_hash, .time_ms = 6, .max_memory_kb = 1024, .parallel_threads = 1 }, pbkdf2 = { .type = CRYPT_KDF_PBKDF2, - .hash = DEFAULT_LUKS1_HASH, + .hash = default_luks1_hash, .time_ms = 9 }, bad = { .type = "hamster_pbkdf", - .hash = DEFAULT_LUKS1_HASH + .hash = default_luks1_hash }; struct crypt_params_plain params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 @@ -2588,7 +2758,7 @@ static void Pbkdf(void) OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); OK_(crypt_set_pbkdf_type(cd, NULL)); NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS1_ITER_TIME); + EQ_(pbkdf->time_ms, default_luks1_iter_time); CRYPT_FREE(cd); // test value set in crypt_set_iteration_time() can be obtained via following crypt_get_pbkdf_type() OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); @@ -2598,7 +2768,7 @@ static void Pbkdf(void) EQ_(pbkdf->time_ms, 42); // test crypt_get_pbkdf_type() returns expected values for LUKSv1 OK_(strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); EQ_(pbkdf->max_memory_kb, 0); EQ_(pbkdf->parallel_threads, 0); crypt_set_iteration_time(cd, 43); @@ -2629,11 +2799,11 @@ static void Pbkdf(void) OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, mode, NULL, NULL, 32, NULL)); NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd)); - OK_(strcmp(pbkdf->type, DEFAULT_LUKS2_PBKDF)); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS2_ITER_TIME); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); - EQ_(pbkdf->parallel_threads, _min(cpus_online(), DEFAULT_LUKS2_PARALLEL_THREADS)); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); // set and verify argon2 type OK_(crypt_set_pbkdf_type(cd, &argon2)); NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd)); @@ -2654,11 +2824,11 @@ static void Pbkdf(void) crypt_set_iteration_time(cd, 1); // it's supposed to override this call OK_(crypt_set_pbkdf_type(cd, NULL)); NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd)); - OK_(strcmp(pbkdf->type, DEFAULT_LUKS2_PBKDF)); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS2_ITER_TIME); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); - EQ_(pbkdf->parallel_threads, _min(cpus_online(), DEFAULT_LUKS2_PARALLEL_THREADS)); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); // try to pass illegal values argon2.parallel_threads = 0; FAIL_(crypt_set_pbkdf_type(cd, &argon2), "Parallel threads can't be 0"); @@ -2676,7 +2846,7 @@ static void Pbkdf(void) bad.hash = NULL; FAIL_(crypt_set_pbkdf_type(cd, &bad), "Hash member is empty"); bad.type = NULL; - bad.hash = DEFAULT_LUKS1_HASH; + bad.hash = default_luks1_hash; FAIL_(crypt_set_pbkdf_type(cd, &bad), "Pbkdf type member is empty"); bad.hash = "hamster_hash"; FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Unknown hash member"); @@ -2685,18 +2855,18 @@ static void Pbkdf(void) OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_load(cd, CRYPT_LUKS, NULL)); NOTNULL_(pbkdf = crypt_get_pbkdf_type(cd)); - OK_(strcmp(pbkdf->type, DEFAULT_LUKS2_PBKDF)); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS2_ITER_TIME); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); - EQ_(pbkdf->parallel_threads, _min(cpus_online(), DEFAULT_LUKS2_PARALLEL_THREADS)); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); crypt_set_iteration_time(cd, 1); OK_(crypt_load(cd, CRYPT_LUKS, NULL)); - OK_(strcmp(pbkdf->type, DEFAULT_LUKS2_PBKDF)); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); EQ_(pbkdf->time_ms, 1); EQ_(pbkdf->max_memory_kb, adjusted_pbkdf_memory()); - EQ_(pbkdf->parallel_threads, _min(cpus_online(), DEFAULT_LUKS2_PARALLEL_THREADS)); + EQ_(pbkdf->parallel_threads, _min(cpus_online(), default_luks2_parallel_threads)); CRYPT_FREE(cd); // test crypt_set_pbkdf_type() overwrites invalid value set by crypt_set_iteration_time() @@ -2734,11 +2904,11 @@ static void Pbkdf(void) pbkdf2.time_ms = 9; pbkdf2.hash = NULL; FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Hash is mandatory for pbkdf2"); - pbkdf2.hash = "sha1"; + pbkdf2.hash = "sha256"; OK_(crypt_set_pbkdf_type(cd, &pbkdf2)); argon2.time_ms = 9; - argon2.hash = "sha1"; // will be ignored + argon2.hash = "sha256"; // will be ignored OK_(crypt_set_pbkdf_type(cd, &argon2)); argon2.hash = NULL; OK_(crypt_set_pbkdf_type(cd, &argon2)); @@ -2747,17 +2917,17 @@ static void Pbkdf(void) NOTNULL_(pbkdf = crypt_get_pbkdf_default(CRYPT_LUKS1)); OK_(strcmp(pbkdf->type, CRYPT_KDF_PBKDF2)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS1_ITER_TIME); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); + EQ_(pbkdf->time_ms, default_luks1_iter_time); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); EQ_(pbkdf->max_memory_kb, 0); EQ_(pbkdf->parallel_threads, 0); NOTNULL_(pbkdf = crypt_get_pbkdf_default(CRYPT_LUKS2)); - OK_(strcmp(pbkdf->type, DEFAULT_LUKS2_PBKDF)); - EQ_(pbkdf->time_ms, DEFAULT_LUKS2_ITER_TIME); - OK_(strcmp(pbkdf->hash, DEFAULT_LUKS1_HASH)); - EQ_(pbkdf->max_memory_kb, DEFAULT_LUKS2_MEMORY_KB); - EQ_(pbkdf->parallel_threads, DEFAULT_LUKS2_PARALLEL_THREADS); + OK_(strcmp(pbkdf->type, default_luks2_pbkdf)); + EQ_(pbkdf->time_ms, default_luks2_iter_time); + OK_(strcmp(pbkdf->hash, default_luks1_hash)); + EQ_(pbkdf->max_memory_kb, default_luks2_memory_kb); + EQ_(pbkdf->parallel_threads, default_luks2_parallel_threads); NULL_(pbkdf = crypt_get_pbkdf_default(CRYPT_PLAIN)); @@ -2768,9 +2938,9 @@ static void Luks2KeyslotAdd(void) { char key[128], key2[128], key_ret[128]; const char *cipher = "aes", *cipher_mode="xts-plain64"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - const char *mk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; - size_t key_ret_len, key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_ret_len, key_size = strlen(vk_hex) / 2; uint64_t r_payload_offset; struct crypt_pbkdf_type pbkdf = { .type = "argon2i", @@ -2782,11 +2952,11 @@ static void Luks2KeyslotAdd(void) }; struct crypt_params_luks2 params2 = { .pbkdf = &pbkdf, - .sector_size = SECTOR_SIZE + .sector_size = TST_SECTOR_SIZE }; - crypt_decode_key(key, mk_hex, key_size); - crypt_decode_key(key2, mk_hex2, key_size); + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key2, vk_hex2, key_size); /* Cannot use Argon2 in FIPS */ if (_fips_mode) { @@ -2907,19 +3077,13 @@ static void Luks2KeyslotParams(void) char key[128], key2[128]; const char *cipher = "aes", *cipher_mode="xts-plain64"; const char *cipher_spec = "aes-xts-plain64", *cipher_keyslot = "aes-cbc-essiv:sha256"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - const char *mk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; - size_t key_size_ret, key_size = strlen(mk_hex) / 2, keyslot_key_size = 16; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size_ret, key_size = strlen(vk_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); + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key2, vk_hex2, key_size); OK_(prepare_keyfile(KEYFILE1, PASSPHRASE, strlen(PASSPHRASE))); OK_(prepare_keyfile(KEYFILE2, PASSPHRASE1, strlen(PASSPHRASE1))); @@ -2930,7 +3094,7 @@ static void Luks2KeyslotParams(void) EQ_(key_size, 2 * keyslot_key_size); /* test crypt_keyslot_add_by_key */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); 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)); @@ -2989,7 +3153,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); - OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); 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); @@ -3018,7 +3182,7 @@ static void Luks2KeyslotParams(void) /* LUKS1 compatible calls */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); 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)); @@ -3030,7 +3194,7 @@ static void Luks2KeyslotParams(void) /* LUKS2 cipher null checks */ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - OK_(crypt_set_pbkdf_type(cd, &fast_pbkdf)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); 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"); @@ -3069,7 +3233,7 @@ static void Luks2ActivateByKeyring(void) // prepare the device OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); - crypt_set_iteration_time(cd, 1); + OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, 32, NULL)); EQ_(crypt_keyslot_add_by_volume_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 0); EQ_(crypt_keyslot_add_by_key(cd, 1, NULL, 32, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT), 1); @@ -3130,21 +3294,21 @@ static void Luks2Requirements(void) const char *token, *json = "{\"type\":\"test_token\",\"keyslots\":[]}"; struct crypt_pbkdf_type argon2 = { .type = CRYPT_KDF_ARGON2I, - .hash = DEFAULT_LUKS1_HASH, + .hash = default_luks1_hash, .time_ms = 6, .max_memory_kb = 1024, .parallel_threads = 1 }, pbkdf2 = { .type = CRYPT_KDF_PBKDF2, - .hash = DEFAULT_LUKS1_HASH, + .hash = default_luks1_hash, .time_ms = 9 }; struct crypt_token_params_luks2_keyring params_get, params = { .key_description = KEY_DESC_TEST0 }; - OK_(prepare_keyfile(KEYFILE1, "aaa", 3)); - OK_(prepare_keyfile(KEYFILE2, "xxx", 3)); + OK_(prepare_keyfile(KEYFILE1, PASSPHRASE, strlen(PASSPHRASE))); + OK_(prepare_keyfile(KEYFILE2, PASSPHRASE1, strlen(PASSPHRASE1))); /* crypt_load (unrestricted) */ OK_(crypt_init(&cd, DEVICE_5)); @@ -3187,15 +3351,22 @@ static void Luks2Requirements(void) FAIL_((r = crypt_set_label(cd, "label", "subsystem")), "Unmet requirements detected"); EQ_(r, -ETXTBSY); + /* crypt_get_label (unrestricted) */ + NOTNULL_(crypt_get_label(cd)); + OK_(strcmp("", crypt_get_label(cd))); + /* crypt_get_subsystem (unrestricted) */ + NOTNULL_(crypt_get_subsystem(cd)); + OK_(strcmp("", crypt_get_subsystem(cd))); + /* crypt_repair (with current repair capabilities it's unrestricted) */ OK_(crypt_repair(cd, CRYPT_LUKS2, NULL)); /* crypt_keyslot_add_passphrase (restricted) */ - FAIL_((r = crypt_keyslot_add_by_passphrase(cd, CRYPT_ANY_SLOT, "aaa", 3, "bbb", 3)), "Unmet requirements detected"); + FAIL_((r = crypt_keyslot_add_by_passphrase(cd, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), "bbb", 3)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_keyslot_change_by_passphrase (restricted) */ - FAIL_((r = crypt_keyslot_change_by_passphrase(cd, CRYPT_ANY_SLOT, 9, "aaa", 3, "bbb", 3)), "Unmet requirements detected"); + FAIL_((r = crypt_keyslot_change_by_passphrase(cd, CRYPT_ANY_SLOT, 9, PASSPHRASE, strlen(PASSPHRASE), "bbb", 3)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_keyslot_add_by_keyfile (restricted) */ @@ -3207,18 +3378,18 @@ static void Luks2Requirements(void) EQ_(r, -ETXTBSY); /* crypt_volume_key_get (unrestricted, but see below) */ - OK_(crypt_volume_key_get(cd, 0, key, &key_size, "aaa", 3)); + OK_(crypt_volume_key_get(cd, 0, key, &key_size, PASSPHRASE, strlen(PASSPHRASE))); /* crypt_keyslot_add_by_volume_key (restricted) */ - FAIL_((r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, key, key_size, "xxx", 3)), "Unmet requirements detected"); + FAIL_((r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, key, key_size, PASSPHRASE1, strlen(PASSPHRASE1))), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_keyslot_add_by_key (restricted) */ - FAIL_((r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, NULL, key_size, "xxx", 3, CRYPT_VOLUME_KEY_NO_SEGMENT)), "Unmet requirements detected"); + FAIL_((r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, NULL, key_size, PASSPHRASE1, strlen(PASSPHRASE1), CRYPT_VOLUME_KEY_NO_SEGMENT)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_keyslot_add_by_key (restricted) */ - FAIL_((r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, key, key_size, "xxx", 3, 0)), "Unmet requirements detected"); + FAIL_((r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, key, key_size, PASSPHRASE1, strlen(PASSPHRASE1), 0)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_persistent_flasgs_set (restricted) */ @@ -3227,13 +3398,13 @@ static void Luks2Requirements(void) /* crypt_persistent_flasgs_get (unrestricted) */ OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags)); - EQ_(flags, (uint32_t) CRYPT_REQUIREMENT_UNKNOWN); + EQ_(flags, CRYPT_REQUIREMENT_UNKNOWN); /* crypt_activate_by_passphrase (restricted for activation only) */ - FAIL_((r = crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, 0)), "Unmet requirements detected"); + FAIL_((r = crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), 0)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); - OK_(crypt_activate_by_passphrase(cd, NULL, 0, "aaa", 3, 0)); - OK_(crypt_activate_by_passphrase(cd, NULL, 0, "aaa", 3, t_dm_crypt_keyring_support() ? CRYPT_ACTIVATE_KEYRING_KEY : 0)); + OK_(crypt_activate_by_passphrase(cd, NULL, 0, PASSPHRASE, strlen(PASSPHRASE), 0)); + OK_(crypt_activate_by_passphrase(cd, NULL, 0, PASSPHRASE, strlen(PASSPHRASE), t_dm_crypt_keyring_support() ? CRYPT_ACTIVATE_KEYRING_KEY : 0)); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); /* crypt_activate_by_keyfile (restricted for activation only) */ @@ -3250,7 +3421,7 @@ static void Luks2Requirements(void) #ifdef KERNEL_KEYRING if (t_dm_crypt_keyring_support()) { - kid = add_key("user", KEY_DESC_TEST0, "aaa", 3, KEY_SPEC_THREAD_KEYRING); + kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE, strlen(PASSPHRASE), KEY_SPEC_THREAD_KEYRING); NOTFAIL_(kid, "Test or kernel keyring are broken."); /* crypt_activate_by_keyring (restricted for activation only) */ @@ -3258,6 +3429,8 @@ static void Luks2Requirements(void) EQ_(r, t_dm_crypt_keyring_support() ? -ETXTBSY : -EINVAL); OK_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST0, 0, 0)); OK_(crypt_activate_by_keyring(cd, NULL, KEY_DESC_TEST0, 0, CRYPT_ACTIVATE_KEYRING_KEY)); + + NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken."); } #endif @@ -3343,10 +3516,15 @@ static void Luks2Requirements(void) /* crypt_activate_by_token (restricted for activation only) */ #ifdef KERNEL_KEYRING if (t_dm_crypt_keyring_support()) { + kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE, strlen(PASSPHRASE), KEY_SPEC_THREAD_KEYRING); + NOTFAIL_(kid, "Test or kernel keyring are broken."); + FAIL_((r = crypt_activate_by_token(cd, CDEVICE_1, 1, NULL, 0)), ""); // supposed to be silent EQ_(r, -ETXTBSY); OK_(crypt_activate_by_token(cd, NULL, 1, NULL, 0)); OK_(crypt_activate_by_token(cd, NULL, 1, NULL, CRYPT_ACTIVATE_KEYRING_KEY)); + + NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken."); } #endif OK_(get_luks2_offsets(0, 8192, 0, NULL, &r_payload_offset)); @@ -3358,7 +3536,7 @@ static void Luks2Requirements(void) CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_load(cd, CRYPT_LUKS, NULL)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, 0)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), 0)); OK_(crypt_header_backup(cd, CRYPT_LUKS2, BACKUP_FILE)); /* replace header with no requirements */ OK_(_system("dd if=" REQS_LUKS2_HEADER " of=" DMDIR L_DEVICE_OK " bs=1M count=4 oflag=direct 2>/dev/null", 1)); @@ -3396,7 +3574,7 @@ static void Luks2Requirements(void) OK_(crypt_init_by_name(&cd, CDEVICE_1)); /* crypt_resume_by_passphrase (restricted) */ - FAIL_((r = crypt_resume_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3)), "Unmet requirements detected"); + FAIL_((r = crypt_resume_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE))), "Unmet requirements detected"); EQ_(r, -ETXTBSY); /* crypt_resume_by_keyfile (restricted) */ @@ -3410,13 +3588,13 @@ static void Luks2Requirements(void) OK_(_system("dd if=" NO_REQS_LUKS2_HEADER " of=" DMDIR L_DEVICE_OK " bs=1M count=4 oflag=direct 2>/dev/null", 1)); OK_(crypt_init_by_name(&cd, CDEVICE_1)); - OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3)); + OK_(crypt_resume_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE))); CRYPT_FREE(cd); OK_(_system("dd if=" REQS_LUKS2_HEADER " of=" DMDIR L_DEVICE_OK " bs=1M count=4 oflag=direct 2>/dev/null", 1)); OK_(crypt_init_by_name(&cd, CDEVICE_1)); /* load VK in keyring */ - OK_(crypt_activate_by_passphrase(cd, NULL, 0, "aaa", 3, t_dm_crypt_keyring_support() ? CRYPT_ACTIVATE_KEYRING_KEY : 0)); + OK_(crypt_activate_by_passphrase(cd, NULL, 0, PASSPHRASE, strlen(PASSPHRASE), t_dm_crypt_keyring_support() ? CRYPT_ACTIVATE_KEYRING_KEY : 0)); /* crypt_resize (restricted) */ FAIL_((r = crypt_resize(cd, CDEVICE_1, 1)), "Unmet requirements detected"); EQ_(r, -ETXTBSY); @@ -3452,7 +3630,6 @@ static void Luks2Integrity(void) .integrity = "hmac(sha256)" }; size_t key_size = 32 + 32; - const char *passphrase = "blabla"; const char *cipher = "aes"; const char *cipher_mode = "xts-random"; int ret; @@ -3466,8 +3643,8 @@ static void Luks2Integrity(void) return; } - 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_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); GE_(crypt_status(cd, CDEVICE_2), CRYPT_ACTIVE); CRYPT_FREE(cd); @@ -3487,27 +3664,6 @@ static void Luks2Integrity(void) CRYPT_FREE(cd); } -static int set_fast_pbkdf(struct crypt_device *cd) -{ - struct crypt_pbkdf_type pbkdf = { - .type = "argon2id", - .hash = "sha256", - .iterations = 4, - .max_memory_kb = 32, - .parallel_threads = 1, - .flags = CRYPT_PBKDF_NO_BENCHMARK - }; - - /* Cannot use Argon2 in FIPS */ - if (_fips_mode) { - pbkdf.type = CRYPT_KDF_PBKDF2; - pbkdf.parallel_threads = 0; - pbkdf.max_memory_kb = 0; - pbkdf.iterations = 1000; - } - return crypt_set_pbkdf_type(cd, &pbkdf); -} - static int check_flag(uint32_t flags, uint32_t flag) { return (flags & flag) ? 0 : -1; @@ -3518,17 +3674,17 @@ static void Luks2Refresh(void) uint64_t r_payload_offset; char key[128], key1[128]; const char *cipher = "aes", *mode = "xts-plain64"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c645be6a5b84818afe7a78a6de7a1a"; - const char *mk_hex2 = "bb22158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c645be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb22158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size = strlen(vk_hex) / 2; struct crypt_params_luks2 params = { .sector_size = 512, .integrity = "aead" }; struct crypt_active_device cad = {}; - crypt_decode_key(key, mk_hex, key_size); - crypt_decode_key(key1, mk_hex2, key_size); + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key1, vk_hex2, key_size); OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000)); @@ -3540,36 +3696,36 @@ static void Luks2Refresh(void) OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(set_fast_pbkdf(cd)); OK_(crypt_format(cd, CRYPT_LUKS2, cipher, mode, NULL, key, 32, NULL)); - OK_(crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, key, 32, "aaa", 3)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, 0)); + OK_(crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, key, 32, PASSPHRASE, strlen(PASSPHRASE))); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), 0)); /* check we can refresh significant flags */ if (t_dm_crypt_discard_support()) { - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_ALLOW_DISCARDS)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_ALLOW_DISCARDS)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_ALLOW_DISCARDS)); cad.flags = 0; } if (t_dm_crypt_cpu_switch_support()) { - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SAME_CPU_CRYPT)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SAME_CPU_CRYPT)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SAME_CPU_CRYPT)); cad.flags = 0; - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); cad.flags = 0; - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); cad.flags = 0; } OK_(crypt_volume_key_keyring(cd, 0)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_KEYRING_KEY), "Unexpected flag raised."); cad.flags = 0; @@ -3577,7 +3733,7 @@ static void Luks2Refresh(void) #ifdef KERNEL_KEYRING if (t_dm_crypt_keyring_support()) { OK_(crypt_volume_key_keyring(cd, 1)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_KEYRING_KEY)); cad.flags = 0; @@ -3586,26 +3742,26 @@ static void Luks2Refresh(void) /* multiple flags at once */ if (t_dm_crypt_discard_support() && t_dm_crypt_cpu_switch_support()) { - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS | CRYPT_ACTIVATE_ALLOW_DISCARDS)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS | CRYPT_ACTIVATE_ALLOW_DISCARDS)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS | CRYPT_ACTIVATE_ALLOW_DISCARDS)); cad.flags = 0; } /* do not allow reactivation with read-only (and drop flag silently because activation behaves exactly same) */ - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_READONLY)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_READONLY)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_READONLY), "Reactivated with read-only flag."); cad.flags = 0; /* reload flag is dropped silently */ OK_(crypt_deactivate(cd, CDEVICE_1)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH)); /* check read-only flag is not lost after reload */ OK_(crypt_deactivate(cd, CDEVICE_1)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_READONLY)); - OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_READONLY)); + OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_READONLY)); cad.flags = 0; @@ -3613,7 +3769,7 @@ static void Luks2Refresh(void) /* check LUKS2 with auth. enc. reload */ OK_(crypt_init(&cd2, DMDIR L_DEVICE_WRONG)); if (!crypt_format(cd2, CRYPT_LUKS2, "aes", "gcm-random", crypt_get_uuid(cd), key, 32, ¶ms)) { - OK_(crypt_keyslot_add_by_volume_key(cd2, 0, key, 32, "aaa", 3)); + OK_(crypt_keyslot_add_by_volume_key(cd2, 0, key, 32, PASSPHRASE, strlen(PASSPHRASE))); OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, 32, 0)); OK_(crypt_activate_by_volume_key(cd2, CDEVICE_2, key, 32, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_NO_JOURNAL)); OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad)); @@ -3623,11 +3779,11 @@ static void Luks2Refresh(void) OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad)); OK_(check_flag(cad.flags, CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)); cad.flags = 0; - OK_(crypt_activate_by_passphrase(cd2, CDEVICE_2, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH)); + OK_(crypt_activate_by_passphrase(cd2, CDEVICE_2, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH)); OK_(crypt_get_active_device(cd2, CDEVICE_2, &cad)); FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_NO_JOURNAL), ""); FAIL_(check_flag(cad.flags, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS), ""); - FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS2/aead context"); + FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS2/aead context"); OK_(crypt_deactivate(cd2, CDEVICE_2)); } else { printf("WARNING: cannot format integrity device, skipping few reload tests.\n"); @@ -3637,8 +3793,8 @@ static void Luks2Refresh(void) /* Use LUKS1 context on LUKS2 device */ OK_(crypt_init(&cd2, DMDIR L_DEVICE_1S)); OK_(crypt_format(cd2, CRYPT_LUKS1, cipher, mode, crypt_get_uuid(cd), key, 32, NULL)); - OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, NULL, 32, "aaa", 3)); - FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS1 context"); + OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, NULL, 32, PASSPHRASE, strlen(PASSPHRASE))); + FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH), "Refreshed LUKS2 device with LUKS1 context"); CRYPT_FREE(cd2); /* Use PLAIN context on LUKS2 device */ @@ -3654,8 +3810,8 @@ static void Luks2Refresh(void) OK_(crypt_init(&cd2, DMDIR L_DEVICE_WRONG)); OK_(set_fast_pbkdf(cd2)); OK_(crypt_format(cd2, CRYPT_LUKS2, cipher, mode, crypt_get_uuid(cd), key, 32, NULL)); - OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, key, 32, "aaa", 3)); - FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, "aaa", 3, CRYPT_ACTIVATE_REFRESH), "Refreshed dm-crypt mapped over mismatching data device"); + OK_(crypt_keyslot_add_by_volume_key(cd2, CRYPT_ANY_SLOT, key, 32, PASSPHRASE, strlen(PASSPHRASE))); + FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, 0, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ACTIVATE_REFRESH), "Refreshed dm-crypt mapped over mismatching data device"); OK_(crypt_deactivate(cd, CDEVICE_1)); @@ -3685,15 +3841,26 @@ static void Luks2Flags(void) flags = CRYPT_ACTIVATE_ALLOW_DISCARDS | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS; OK_(crypt_persistent_flags_set(cd, CRYPT_FLAGS_ACTIVATION, flags)); - flags = (uint32_t)~0; + flags = ~UINT32_C(0); OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_ACTIVATION, &flags)); EQ_(flags,CRYPT_ACTIVATE_ALLOW_DISCARDS | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS); + /* label and subsystem (second label */ + OK_(crypt_set_label(cd, "label", "subsystem")); + OK_(strcmp("label", crypt_get_label(cd))); + OK_(strcmp("subsystem", crypt_get_subsystem(cd))); + + OK_(crypt_set_label(cd, NULL, NULL)); + OK_(strcmp("", crypt_get_label(cd))); + OK_(strcmp("", crypt_get_subsystem(cd))); + CRYPT_FREE(cd); } #if KERNEL_KEYRING && USE_LUKS2_REENCRYPTION -static int test_progress(uint64_t size, uint64_t offset, void *usrptr) +static int test_progress(uint64_t size __attribute__((unused)), + uint64_t offset __attribute__((unused)), + void *usrptr __attribute__((unused))) { while (--test_progress_steps) return 0; @@ -3724,15 +3891,16 @@ static void Luks2Reencryption(void) struct crypt_params_reencrypt retparams = {}, rparams = { .direction = CRYPT_REENCRYPT_FORWARD, .resilience = "checksum", - .hash = "sha1", + .hash = "sha256", .luks2 = ¶ms2, }; + dev_t devno; - const char *mk_hex = "bb21babe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21babe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; char key[128]; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); /* reencryption currently depends on kernel keyring support in dm-crypt */ if (!t_dm_crypt_keyring_support()) @@ -3775,7 +3943,7 @@ static void Luks2Reencryption(void) OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &getflags)); EQ_(getflags & CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 0); - FAIL_(crypt_reencrypt(cd, NULL), "Reencryption context not initialized."); + FAIL_(crypt_reencrypt_run(cd, NULL, NULL), "Reencryption context not initialized."); rparams.flags &= ~CRYPT_REENCRYPT_RESUME_ONLY; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams)); @@ -3808,7 +3976,7 @@ static void Luks2Reencryption(void) rparams.flags = 0; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); /* check keyslots are reassigned to segment after reencryption */ EQ_(crypt_keyslot_status(cd, 0), CRYPT_SLOT_INACTIVE); @@ -3832,10 +4000,10 @@ static void Luks2Reencryption(void) FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 9, 21, "aes", "xts-plain64", &rparams), "Invalid device size alignment."); OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &getflags)); EQ_(getflags & CRYPT_REQUIREMENT_ONLINE_REENCRYPT, CRYPT_REQUIREMENT_ONLINE_REENCRYPT); - FAIL_(crypt_reencrypt(cd, NULL), "Reencryption context not initialized."); + FAIL_(crypt_reencrypt_run(cd, NULL, NULL), "Reencryption context not initialized."); rparams.device_size = 16; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 9, 21, "aes", "xts-plain64", &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &getflags)); EQ_(getflags & CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 0); @@ -3867,9 +4035,9 @@ static void Luks2Reencryption(void) rparams.hash = "hamSter"; FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams), "Invalid resilience hash."); - rparams.hash = "sha1"; + rparams.hash = "sha256"; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); /* FIXME: this is a bug, but not critical (data shift parameter is ignored after initialization) */ //rparams.data_shift = 8; @@ -3896,7 +4064,7 @@ static void Luks2Reencryption(void) FAIL_(crypt_reencrypt_init_by_passphrase(cd2, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams), "Reencryption already running."); rparams.flags = 0; FAIL_(crypt_reencrypt_init_by_passphrase(cd2, NULL, PASSPHRASE, strlen(PASSPHRASE), 21, 9, "aes", "xts-plain64", &rparams), "Reencryption already running."); - FAIL_(crypt_reencrypt(cd2, NULL), "Invalid reencryption context."); + FAIL_(crypt_reencrypt_run(cd2, NULL, NULL), "Invalid reencryption context."); OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &getflags)); EQ_(getflags & CRYPT_REQUIREMENT_ONLINE_REENCRYPT, CRYPT_REQUIREMENT_ONLINE_REENCRYPT); OK_(crypt_persistent_flags_get(cd2, CRYPT_FLAGS_REQUIREMENTS, &getflags)); @@ -3905,7 +4073,7 @@ static void Luks2Reencryption(void) EQ_(crypt_reencrypt_status(cd2, NULL), CRYPT_REENCRYPT_CLEAN); FAIL_(crypt_activate_by_passphrase(cd2, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), "Reencryption already in progress."); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), "Reencryption already in progress."); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); CRYPT_FREE(cd2); @@ -3923,8 +4091,8 @@ static void Luks2Reencryption(void) EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, 1, "aes", "xts-plain64", &rparams), 2); /* interrupt reencryption after 'test_progress_steps' */ - test_progress_steps = 1; - OK_(crypt_reencrypt(cd, &test_progress)); + test_progress_steps = 2; + OK_(crypt_reencrypt_run(cd, &test_progress, NULL)); EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_CLEAN); NOTFAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), "Could not activate device in reencryption."); @@ -3943,7 +4111,7 @@ static void Luks2Reencryption(void) rparams.device_size = 2; rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; NOTFAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, 1, "aes", "xts-plain64", &rparams), "Failed to initialize reencryption."); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 1, PASSPHRASE, strlen(PASSPHRASE), 0), 1); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); @@ -4016,7 +4184,7 @@ static void Luks2Reencryption(void) EQ_(crypt_get_data_offset(cd), 32776); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, 1, "aes", "xts-plain64", &rparams), 2); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_set_pbkdf_type(cd, &pbkdf)); @@ -4049,7 +4217,7 @@ static void Luks2Reencryption(void) EQ_(crypt_get_data_offset(cd), 32760); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, 0, "aes", "xts-plain64", &rparams), 2); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); @@ -4078,7 +4246,7 @@ static void Luks2Reencryption(void) EQ_(cad.size, 8); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; EQ_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_1, PASSPHRASE, strlen(PASSPHRASE), 0, 1, "aes", "xts-plain64", &rparams), 2); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -4117,12 +4285,12 @@ static void Luks2Reencryption(void) EQ_(crypt_get_data_offset(cd), 8192); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, NULL, NULL, &rparams), 0); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); _cleanup_dmdevices(); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); - OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2+1)); + OK_(create_dmdevice_over_loop(L_DEVICE_OK, 8*1024*2+1)); /* encryption with datashift and moved segment (data shift + 1 sector) */ OK_(crypt_init(&cd, DMDIR H_DEVICE)); @@ -4137,16 +4305,16 @@ static void Luks2Reencryption(void) EQ_(crypt_get_data_offset(cd), 8192); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 30, NULL, NULL, &rparams), 0); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); _cleanup_dmdevices(); OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); - OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2)); + OK_(create_dmdevice_over_loop(L_DEVICE_OK, 2*8200)); OK_(crypt_init(&cd, DMDIR H_DEVICE)); - /* encryption with datashift and moved segment (data shift + data offset > device size) */ + /* encryption with datashift and moved segment (data shift + data offset <= device size) */ memset(&rparams, 0, sizeof(rparams)); params2.sector_size = 512; params2.data_device = DMDIR L_DEVICE_OK; @@ -4179,7 +4347,7 @@ static void Luks2Reencryption(void) rparams.resilience = "none"; rparams.max_hotzone_size = 2048; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 6, CRYPT_ANY_SLOT, NULL, NULL, &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); @@ -4200,7 +4368,23 @@ static void Luks2Reencryption(void) rparams.resilience = "none"; rparams.max_hotzone_size = 2048; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 6, CRYPT_ANY_SLOT, NULL, NULL, &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); + CRYPT_FREE(cd); + + /* decryption forward (online) */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + params2.data_device = NULL; + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, ¶ms2)); + OK_(crypt_set_pbkdf_type(cd, &pbkdf)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 6, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 6); + EQ_(crypt_activate_by_passphrase(cd, CDEVICE_2, 6, PASSPHRASE, strlen(PASSPHRASE), 0), 6); + memset(&rparams, 0, sizeof(rparams)); + rparams.mode = CRYPT_REENCRYPT_DECRYPT; + rparams.direction = CRYPT_REENCRYPT_FORWARD; + rparams.resilience = "none"; + rparams.max_hotzone_size = 2048; + OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_2, PASSPHRASE, strlen(PASSPHRASE), 6, CRYPT_ANY_SLOT, NULL, NULL, &rparams)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); CRYPT_FREE(cd); /* decryption with data shift */ @@ -4224,7 +4408,7 @@ static void Luks2Reencryption(void) rparams.data_shift = r_header_size; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 6, CRYPT_ANY_SLOT, NULL, NULL, &rparams)); EQ_(crypt_get_data_offset(cd), 0); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); remove(BACKUP_FILE); CRYPT_FREE(cd); @@ -4237,6 +4421,8 @@ static void Luks2Reencryption(void) EQ_(crypt_activate_by_passphrase(cd, CDEVICE_2, 6, PASSPHRASE, strlen(PASSPHRASE), 0), 6); OK_(t_device_size(DMDIR CDEVICE_2, &r_size_1)); EQ_(r_size_1, 512); + // store devno for later size check + OK_(t_get_devno(CDEVICE_2, &devno)); // create placeholder device to block automatic deactivation after decryption OK_(_system("dmsetup create " CDEVICE_1 " --table \"0 1 linear " DMDIR CDEVICE_2 " 0\"", 1)); remove(BACKUP_FILE); @@ -4254,9 +4440,9 @@ static void Luks2Reencryption(void) rparams.data_shift = r_header_size; OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_2, PASSPHRASE, strlen(PASSPHRASE), 6, CRYPT_ANY_SLOT, NULL, NULL, &rparams)); EQ_(crypt_get_data_offset(cd), 0); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); remove(BACKUP_FILE); - OK_(t_device_size(DMDIR CDEVICE_2, &r_size_1)); + OK_(t_device_size_by_devno(devno, &r_size_1)); EQ_(r_size_1, 512); OK_(_system("dmsetup remove " DM_RETRY CDEVICE_1 DM_NOSTDERR, 0)); CRYPT_FREE(cd); @@ -4287,7 +4473,7 @@ static void Luks2Reencryption(void) rparams.luks2 = ¶ms2; OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_1, PASSPHRASE, strlen(PASSPHRASE), 6, 1, "aes", "cbc-essiv:sha256", &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); OK_(crypt_init_data_device(&cd2, IMAGE_EMPTY_SMALL, DMDIR L_DEVICE_OK)); OK_(crypt_load(cd2, CRYPT_LUKS2, NULL)); @@ -4313,9 +4499,9 @@ static void Luks2Reencryption(void) rparams.flags = 0; rparams.max_hotzone_size = 8; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 6, 1, "aes", "cbc-essiv:sha256", &rparams)); - /* reencrypt 8 srectors of device */ - test_progress_steps = 1; - OK_(crypt_reencrypt(cd, &test_progress)); + /* reencrypt 8 sectors of device */ + test_progress_steps = 2; + OK_(crypt_reencrypt_run(cd, &test_progress, NULL)); /* activate another data device with same LUKS2 header (this is wrong, but we can't detect such mistake) */ OK_(crypt_init_data_device(&cd2, IMAGE_EMPTY_SMALL, DMDIR L_DEVICE_OK)); @@ -4326,8 +4512,8 @@ static void Luks2Reencryption(void) /* reencrypt yet another 8 sectors of first device */ rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; OK_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 6, 1, "aes", "cbc-essiv:sha256", &rparams)); - test_progress_steps = 1; - OK_(crypt_reencrypt(cd, &test_progress)); + test_progress_steps = 2; + OK_(crypt_reencrypt_run(cd, &test_progress, NULL)); /* Now active mapping for second data device does not match its metadata */ OK_(crypt_init_data_device(&cd2, IMAGE_EMPTY_SMALL, DMDIR L_DEVICE_OK)); @@ -4359,8 +4545,8 @@ static void Luks2Reencryption(void) rparams.flags = 0; EQ_(crypt_keyslot_add_by_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 1); OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_1, PASSPHRASE, strlen(PASSPHRASE), 6, 1, "aes", "xts-plain64", &rparams)); - test_progress_steps = 1; - OK_(crypt_reencrypt(cd, &test_progress)); + test_progress_steps = 2; + OK_(crypt_reencrypt_run(cd, &test_progress, NULL)); EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_CLEAN); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); EQ_(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS, CRYPT_ACTIVATE_ALLOW_DISCARDS); @@ -4369,7 +4555,7 @@ static void Luks2Reencryption(void) OK_(crypt_init_by_name(&cd, CDEVICE_1)); rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY; OK_(crypt_reencrypt_init_by_passphrase(cd, CDEVICE_1, PASSPHRASE, strlen(PASSPHRASE), 6, 1, "aes", "xts-plain64", &rparams)); - OK_(crypt_reencrypt(cd, NULL)); + OK_(crypt_reencrypt_run(cd, NULL, NULL)); OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); EQ_(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS, CRYPT_ACTIVATE_ALLOW_DISCARDS); EQ_(cad.flags & CRYPT_ACTIVATE_KEYRING_KEY, 0); @@ -4397,27 +4583,447 @@ static void Luks2Reencryption(void) 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_reencrypt_run(cd, NULL, 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); + CRYPT_FREE(cd); + + _cleanup_dmdevices(); + OK_(create_dmdevice_over_loop(L_DEVICE_OK, 2 * r_header_size)); + OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); + + rparams = (struct crypt_params_reencrypt) { + .mode = CRYPT_REENCRYPT_DECRYPT, + .direction = CRYPT_REENCRYPT_FORWARD, + .resilience = "datashift-checksum", + .hash = "sha256", + .data_shift = r_header_size, + .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY | CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT + }; + + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, NULL)); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, NULL, 64, PASSPHRASE, strlen(PASSPHRASE))); + OK_(crypt_header_backup(cd, CRYPT_LUKS2, BACKUP_FILE)); + CRYPT_FREE(cd); + + params2.data_device = DMDIR L_DEVICE_OK; + params2.sector_size = 512; + + /* create detached LUKS2 header (with data_offset == 0) */ + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, ¶ms2)); + EQ_(crypt_get_data_offset(cd), 0); + OK_(set_fast_pbkdf(cd)); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, NULL, 64, PASSPHRASE, strlen(PASSPHRASE))); + CRYPT_FREE(cd); + + /* initiate LUKS2 decryption with datashift on bogus LUKS2 header (data_offset == 0) */ + OK_(crypt_init_data_device(&cd, DMDIR H_DEVICE, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Illegal data offset"); + /* reencryption must not initialize */ + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + CRYPT_FREE(cd); + /* original data device must stay untouched */ + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + CRYPT_FREE(cd); + + OK_(chmod(BACKUP_FILE, S_IRUSR|S_IWUSR)); + OK_(crypt_init_data_device(&cd, BACKUP_FILE, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + + /* simulate read error at first segment beyond data offset*/ + OK_(dmdevice_error_io(L_DEVICE_OK, DMDIR L_DEVICE_OK, DEVICE_ERROR, 0, r_header_size, 8, ERR_RD)); + + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Could not read first data segment"); + CRYPT_FREE(cd); + + /* Device must not be in reencryption */ + OK_(crypt_init_data_device(&cd, BACKUP_FILE, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + /* simulate write error in original LUKS2 header area */ + OK_(dmdevice_error_io(L_DEVICE_OK, DMDIR L_DEVICE_OK, DEVICE_ERROR, 0, 0, 8, ERR_WR)); + + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Could not write first data segment"); + CRYPT_FREE(cd); + + /* Device must not be in reencryption */ + OK_(crypt_init_data_device(&cd, BACKUP_FILE, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + CRYPT_FREE(cd); + remove(BACKUP_FILE); + + /* remove error mapping */ + OK_(dmdevice_error_io(L_DEVICE_OK, DMDIR L_DEVICE_OK, DEVICE_ERROR, 0, 0, 8, ERR_REMOVE)); + + /* test various bogus reencryption resilience parameters */ + rparams = (struct crypt_params_reencrypt) { + .mode = CRYPT_REENCRYPT_DECRYPT, + .direction = CRYPT_REENCRYPT_FORWARD, + .resilience = "checksum", /* should have been datashift-checksum */ + .hash = "sha256", + .data_shift = r_header_size, + .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY | CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT + }; + + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, NULL)); + EQ_(0, crypt_keyslot_add_by_volume_key(cd, 0, NULL, 64, PASSPHRASE, strlen(PASSPHRASE))); + OK_(crypt_header_backup(cd, CRYPT_LUKS2, BACKUP_FILE)); + CRYPT_FREE(cd); + + OK_(chmod(BACKUP_FILE, S_IRUSR|S_IWUSR)); + OK_(crypt_init_data_device(&cd, BACKUP_FILE, DMDIR L_DEVICE_OK)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + /* decryption on device with data offset and no datashift subvariant mode */ + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + rparams.resilience = "journal"; /* should have been datashift-journal */ + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + rparams = (struct crypt_params_reencrypt) { + .mode = CRYPT_REENCRYPT_DECRYPT, + .direction = CRYPT_REENCRYPT_FORWARD, + .resilience = "datashift-checksum", + .hash = "sha256", + .data_shift = 0, /* must be non zero */ + .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY | CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT + }; + + /* datashift = 0 */ + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + rparams.resilience = "datashift-journal"; + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + rparams.resilience = "datashift"; /* datashift only is not supported in decryption mode with moved segment */ + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + CRYPT_FREE(cd); + + OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, ¶ms2)); + EQ_(crypt_keyslot_add_by_volume_key(cd, 21, NULL, 32, PASSPHRASE, strlen(PASSPHRASE)), 21); + + rparams = (struct crypt_params_reencrypt) { + .mode = CRYPT_REENCRYPT_REENCRYPT, + .direction = CRYPT_REENCRYPT_FORWARD, + .resilience = "datashift-checksum", + .hash = "sha256", + .data_shift = r_header_size, + .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY + }; + + /* regular reencryption must not accept datashift subvariants */ + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + rparams.resilience = "datashift-journal"; + FAIL_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 0, CRYPT_ANY_SLOT, NULL, NULL, &rparams), "Invalid reencryption params"); + EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE); + + CRYPT_FREE(cd); _cleanup_dmdevices(); } #endif +static void LuksKeyslotAdd(void) +{ + struct crypt_params_luks2 params = { + .sector_size = 512 + }; + char key[128], key3[128]; +#ifdef KERNEL_KEYRING + int ks; + key_serial_t kid; +#endif + const struct crypt_token_params_luks2_keyring tparams = { + .key_description = KEY_DESC_TEST0 + }; + + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size = strlen(vk_hex) / 2; + const char *cipher = "aes"; + const char *cipher_mode = "cbc-essiv:sha256"; + uint64_t r_payload_offset; + struct crypt_keyslot_context *um1, *um2; + + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key3, vk_hex2, key_size); + + // init test devices + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(H_DEVICE, r_payload_offset + 1)); + + // test support for embedded key (after crypt_format) + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, NULL, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 3, um2, 0), 3); + EQ_(crypt_keyslot_status(cd, 3), CRYPT_SLOT_ACTIVE_LAST); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + CRYPT_FREE(cd); + + // test add by volume key + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE1, strlen(PASSPHRASE1), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, CRYPT_ANY_SLOT, um2, 0), 0); + EQ_(crypt_keyslot_status(cd, 0), CRYPT_SLOT_ACTIVE); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // Add by same passphrase + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 1, um1, 0), 1); + EQ_(crypt_keyslot_status(cd, 1), CRYPT_SLOT_ACTIVE); + crypt_keyslot_context_free(um1); + + // new passphrase can't be provided by key method + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, 1, um1, CRYPT_ANY_SLOT, um2, 0), "Can't get passphrase via selected unlock method"); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // add by keyfile + OK_(prepare_keyfile(KEYFILE1, PASSPHRASE1, strlen(PASSPHRASE1))); + OK_(prepare_keyfile(KEYFILE2, KEY1, strlen(KEY1))); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, 0, um1, 2, um2, 0), 2); + EQ_(crypt_keyslot_status(cd, 2), CRYPT_SLOT_ACTIVE); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // add by same keyfile + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um1)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, 2, um1, 4, um1, 0), 4); + EQ_(crypt_keyslot_status(cd, 4), CRYPT_SLOT_ACTIVE); + crypt_keyslot_context_free(um1); + + // keyslot already exists + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, 3, um1, 0, um2, 0), "Keyslot already exists."); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // generate new unbound key + OK_(crypt_keyslot_context_init_by_volume_key(cd, NULL, 9, &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 10, um2, CRYPT_VOLUME_KEY_NO_SEGMENT), 10); + EQ_(crypt_keyslot_status(cd, 10), CRYPT_SLOT_UNBOUND); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + EQ_(crypt_token_luks2_keyring_set(cd, 3, &tparams), 3); + EQ_(crypt_token_assign_keyslot(cd, 3, 1), 3); + EQ_(crypt_token_assign_keyslot(cd, 3, 3), 3); + + // test unlocking/adding keyslot by LUKS2 token + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + // passphrase not in keyring + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 13, um2, 0), "No token available."); +#ifdef KERNEL_KEYRING + // wrong passphrase in keyring + kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE1, strlen(PASSPHRASE1), KEY_SPEC_THREAD_KEYRING); + NOTFAIL_(kid, "Test or kernel keyring are broken."); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 13, um2, 0), "No token available."); + + // token unlocks keyslot + kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE, strlen(PASSPHRASE), KEY_SPEC_THREAD_KEYRING); + NOTFAIL_(kid, "Test or kernel keyring are broken."); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 13, um2, 0), 13); + EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_ACTIVE); + + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // token provides passphrase for new keyslot + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, 3, um1, 30, um2, 0), 30); + EQ_(crypt_keyslot_status(cd, 30), CRYPT_SLOT_ACTIVE); + OK_(crypt_token_is_assigned(cd, 3, 30)); + + // unlock and add by same token + crypt_keyslot_context_free(um1); + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um1)); + ks = crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, CRYPT_ANY_SLOT, um1, 0); + GE_(ks, 0); + EQ_(crypt_keyslot_status(cd, ks), CRYPT_SLOT_ACTIVE); + OK_(crypt_token_is_assigned(cd, 3, ks)); +#endif + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + CRYPT_FREE(cd); + + _cleanup_dmdevices(); +} + +static void VolumeKeyGet(void) +{ + struct crypt_params_luks2 params = { + .sector_size = 512 + }; + char key[256], key2[256]; +#ifdef KERNEL_KEYRING + key_serial_t kid; + const struct crypt_token_params_luks2_keyring tparams = { + .key_description = KEY_DESC_TEST0 + }; +#endif + + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a" + "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1b"; + size_t key_size = strlen(vk_hex) / 2; + const char *cipher = "aes"; + const char *cipher_mode = "xts-plain64"; + uint64_t r_payload_offset; + struct crypt_keyslot_context *um1, *um2; + + crypt_decode_key(key, vk_hex, key_size); + + OK_(prepare_keyfile(KEYFILE1, PASSPHRASE1, strlen(PASSPHRASE1))); + +#ifdef KERNEL_KEYRING + kid = add_key("user", KEY_DESC_TEST0, PASSPHRASE1, strlen(PASSPHRASE1), KEY_SPEC_THREAD_KEYRING); + NOTFAIL_(kid, "Test or kernel keyring are broken."); +#endif + + // init test devices + OK_(get_luks2_offsets(0, 0, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(H_DEVICE, r_payload_offset + 1)); + + // test support for embedded key (after crypt_format) + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); + key_size--; + FAIL_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL), "buffer too small"); + + // check cached generated volume key can be retrieved + key_size++; + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL)); + OK_(crypt_volume_key_verify(cd, key2, key_size)); + CRYPT_FREE(cd); + + // check we can add keyslot via retrieved key + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key2, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 3, um2, 0), 3); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + CRYPT_FREE(cd); + + // check selected volume key can be retrieved and added + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(set_fast_pbkdf(cd)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + memset(key2, 0, key_size); + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL)); + OK_(memcmp(key, key2, key_size)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key2, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 0, um2, 0), 0); + crypt_keyslot_context_free(um2); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 1, um2, 0), 1); + crypt_keyslot_context_free(um2); +#ifdef KERNEL_KEYRING + EQ_(crypt_token_luks2_keyring_set(cd, 0, &tparams), 0); + EQ_(crypt_token_assign_keyslot(cd, 0, 1), 0); +#endif + crypt_keyslot_context_free(um1); + CRYPT_FREE(cd); + + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS2, NULL)); + // check key context is not usable + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), -EINVAL); + crypt_keyslot_context_free(um1); + + // by passphrase + memset(key2, 0, key_size); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), 0); + OK_(memcmp(key, key2, key_size)); + memset(key2, 0, key_size); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, 0, key2, &key_size, um1), 0); + OK_(memcmp(key, key2, key_size)); + crypt_keyslot_context_free(um1); + + // by keyfile + memset(key2, 0, key_size); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), 1); + OK_(memcmp(key, key2, key_size)); + memset(key2, 0, key_size); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, 1, key2, &key_size, um1), 1); + crypt_keyslot_context_free(um1); + +#ifdef KERNEL_KEYRING + // by token + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um1)); + memset(key2, 0, key_size); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), 1); + OK_(memcmp(key, key2, key_size)); + crypt_keyslot_context_free(um1); +#endif + CRYPT_FREE(cd); + + _remove_keyfiles(); + _cleanup_dmdevices(); +} + +static int _crypt_load_check(struct crypt_device *cd) +{ +#ifdef HAVE_BLKID + return crypt_load(cd, CRYPT_LUKS, NULL); +#else + return -ENOTSUP; +#endif +} + static void Luks2Repair(void) { char rollback[256]; - snprintf(rollback, sizeof(rollback), - "dd if=" IMAGE_PV_LUKS2_SEC ".bcp of=%s bs=1M 2>/dev/null", - DEVICE_6); + GE_(snprintf(rollback, sizeof(rollback), + "dd if=" IMAGE_PV_LUKS2_SEC ".bcp of=%s bs=1M 2>/dev/null", DEVICE_6), 0); OK_(crypt_init(&cd, DEVICE_6)); - FAIL_(crypt_load(cd, CRYPT_LUKS, NULL), "Ambiguous signature detected"); + FAIL_(_crypt_load_check(cd), "Ambiguous signature detected"); FAIL_(crypt_repair(cd, CRYPT_LUKS1, NULL), "Not a LUKS2 device"); /* check explicit LUKS2 repair works */ @@ -4428,7 +5034,7 @@ static void Luks2Repair(void) /* rollback */ OK_(_system(rollback, 1)); - FAIL_(crypt_load(cd, CRYPT_LUKS, NULL), "Ambiguous signature detected"); + FAIL_(_crypt_load_check(cd), "Ambiguous signature detected"); /* check repair with type detection works */ OK_(crypt_repair(cd, CRYPT_LUKS, NULL)); @@ -4440,7 +5046,7 @@ static void Luks2Repair(void) OK_(crypt_init(&cd, DEVICE_6)); OK_(crypt_metadata_locking(cd, 0)); - FAIL_(crypt_load(cd, CRYPT_LUKS, NULL), "Ambiguous signature detected"); + FAIL_(_crypt_load_check(cd), "Ambiguous signature detected"); FAIL_(crypt_repair(cd, CRYPT_LUKS1, NULL), "Not a LUKS2 device"); /* check explicit LUKS2 repair works */ @@ -4451,7 +5057,7 @@ static void Luks2Repair(void) /* rollback */ OK_(_system(rollback, 1)); - FAIL_(crypt_load(cd, CRYPT_LUKS, NULL), "Ambiguous signature detected"); + FAIL_(_crypt_load_check(cd), "Ambiguous signature detected"); /* check repair with type detection works */ OK_(crypt_repair(cd, CRYPT_LUKS, NULL)); @@ -4524,6 +5130,8 @@ int main(int argc, char *argv[]) #if KERNEL_KEYRING && USE_LUKS2_REENCRYPTION RUN_(Luks2Reencryption, "LUKS2 reencryption"); #endif + RUN_(LuksKeyslotAdd, "Adding keyslot via new API"); + RUN_(VolumeKeyGet, "Getting volume key via keyslot context API"); 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 85f7a93..aa430dd 100644 --- a/tests/api-test.c +++ b/tests/api-test.c @@ -1,9 +1,9 @@ /* * cryptsetup library API check functions * - * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2021 Milan Broz - * Copyright (C) 2016-2021 Ondrej Kozina + * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2023 Milan Broz + * Copyright (C) 2016-2023 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,11 +31,9 @@ #include <sys/types.h> #include "api_test.h" -#include "luks.h" +#include "luks1/luks.h" #include "libcryptsetup.h" -#define DMDIR "/dev/mapper/" - #define DEVICE_1_UUID "28632274-8c8a-493f-835b-da802e1c576b" #define DEVICE_EMPTY_name "crypt_zero" #define DEVICE_EMPTY DMDIR DEVICE_EMPTY_name @@ -67,8 +65,8 @@ #define KEYFILE2 "key2.file" #define KEY2 "0123456789abcdef" -#define PASSPHRASE "blabla" -#define PASSPHRASE1 "albalb" +#define PASSPHRASE "blablabl" +#define PASSPHRASE1 "albalbal" #define DEVICE_TEST_UUID "12345678-1234-1234-1234-123456789abc" @@ -110,17 +108,17 @@ static int get_luks_offsets(int metadata_device, return -1; } - sectors_per_stripes_set = DIV_ROUND_UP(keylength*LUKS_STRIPES, SECTOR_SIZE); - current_sector = DIV_ROUND_UP_MODULO(DIV_ROUND_UP(LUKS_PHDR_SIZE_B, SECTOR_SIZE), - LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE); + sectors_per_stripes_set = DIV_ROUND_UP(keylength*LUKS_STRIPES, TST_SECTOR_SIZE); + current_sector = DIV_ROUND_UP_MODULO(DIV_ROUND_UP(LUKS_PHDR_SIZE_B, TST_SECTOR_SIZE), + LUKS_ALIGN_KEYSLOTS / TST_SECTOR_SIZE); for (i=0; i < (LUKS_NUMKEYS - 1); i++) current_sector = DIV_ROUND_UP_MODULO(current_sector + sectors_per_stripes_set, - LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE); + LUKS_ALIGN_KEYSLOTS / TST_SECTOR_SIZE); if (r_header_size) *r_header_size = current_sector + sectors_per_stripes_set; current_sector = DIV_ROUND_UP_MODULO(current_sector + sectors_per_stripes_set, - LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE); + LUKS_ALIGN_KEYSLOTS / TST_SECTOR_SIZE); if (r_payload_offset) { if (metadata_device) @@ -239,13 +237,17 @@ static int _setup(void) char cmd[128]; test_loop_file = strdup(THE_LFILE_TEMPLATE); + if (!test_loop_file) + return 1; + if ((fd=mkstemp(test_loop_file)) == -1) { printf("cannot create temporary file with template %s\n", test_loop_file); return 1; } close(fd); - snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", - test_loop_file, SECTOR_SIZE, TST_LOOP_FILE_SIZE); + if (snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", + test_loop_file, TST_SECTOR_SIZE, TST_LOOP_FILE_SIZE) < 0) + return 1; if (_system(cmd, 1)) return 1; @@ -253,13 +255,17 @@ static int _setup(void) close(fd); tmp_file_1 = strdup(THE_LFILE_TEMPLATE); + if (!tmp_file_1) + return 1; + if ((fd=mkstemp(tmp_file_1)) == -1) { printf("cannot create temporary file with template %s\n", tmp_file_1); return 1; } close(fd); - snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", - tmp_file_1, SECTOR_SIZE, 10); + if (snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=%s bs=%d count=%d 2>/dev/null", + tmp_file_1, TST_SECTOR_SIZE, 10) < 0) + return 1; if (_system(cmd, 1)) return 1; @@ -292,8 +298,12 @@ static int _setup(void) /* Prepare tcrypt images */ _system("tar xJf tcrypt-images.tar.xz 2>/dev/null", 1); - _system("modprobe dm-crypt", 0); - _system("modprobe dm-verity", 0); + _system("modprobe dm-crypt >/dev/null 2>&1", 0); + _system("modprobe dm-verity >/dev/null 2>&1", 0); + _system("modprobe dm-integrity >/dev/null 2>&1", 0); + + if (t_dm_check_versions()) + return 1; _fips_mode = fips_mode(); if (_debug) @@ -308,24 +318,25 @@ static int _setup(void) static void AddDevicePlain(void) { struct crypt_params_plain params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 }; int fd; char key[128], key2[128], path[128]; + struct crypt_keyslot_context *kc = NULL; - const char *passphrase = PASSPHRASE; + const char *passphrase = "blabla"; // hashed hex version of PASSPHRASE - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "ccadd99b16cd3d200c22d6db45d8b6630ef3d936767127347ec8a76ab992c2ea"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t size, r_size; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); FAIL_(crypt_init(&cd, ""), "empty device string"); FAIL_(crypt_init(&cd, DEVICE_WRONG), "nonexistent device name "); FAIL_(crypt_init(&cd, DEVICE_CHAR), "character device as backing device"); @@ -365,7 +376,7 @@ static void AddDevicePlain(void) t_device_size(DEVICE_1,&size); params.hash = NULL; // zero sectors length - params.offset = size >> SECTOR_SHIFT; + params.offset = size >> TST_SECTOR_SHIFT; OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); EQ_(crypt_get_data_offset(cd),params.offset); @@ -373,22 +384,22 @@ static void AddDevicePlain(void) FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0), "invalid device size (0 blocks)"); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); // data part of crypt device is of 1 sector size - params.offset = (size >> SECTOR_SHIFT) - 1; + params.offset = (size >> TST_SECTOR_SHIFT) - 1; CRYPT_FREE(cd); 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)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); - snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1); + GE_(snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1), 0); if (t_device_size(path, &r_size) >= 0) - EQ_(r_size>>SECTOR_SHIFT, 1); + EQ_(r_size >> TST_SECTOR_SHIFT, 1); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); // size > device_size params.offset = 0; - params.size = (size >> SECTOR_SHIFT) + 1; + params.size = (size >> TST_SECTOR_SHIFT) + 1; crypt_init(&cd, DEVICE_1); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0),"Device too small"); @@ -396,7 +407,7 @@ static void AddDevicePlain(void) CRYPT_FREE(cd); // offset == device_size (autodetect size) - params.offset = (size >> SECTOR_SHIFT); + params.offset = (size >> TST_SECTOR_SHIFT); params.size = 0; crypt_init(&cd, DEVICE_1); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); @@ -405,7 +416,7 @@ static void AddDevicePlain(void) CRYPT_FREE(cd); // offset == device_size (user defined size) - params.offset = (size >> SECTOR_SHIFT); + params.offset = (size >> TST_SECTOR_SHIFT); params.size = 123; crypt_init(&cd, DEVICE_1); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); @@ -415,7 +426,7 @@ static void AddDevicePlain(void) // offset+size > device_size params.offset = 42; - params.size = (size >> SECTOR_SHIFT) - params.offset + 1; + params.size = (size >> TST_SECTOR_SHIFT) - params.offset + 1; crypt_init(&cd, DEVICE_1); OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms)); FAIL_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), 0),"Offset and size are beyond device real size"); @@ -424,17 +435,17 @@ static void AddDevicePlain(void) // offset+size == device_size params.offset = 42; - params.size = (size >> SECTOR_SHIFT) - params.offset; + params.size = (size >> TST_SECTOR_SHIFT) - params.offset; 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)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); if (!t_device_size(path, &r_size)) - EQ_((r_size >> SECTOR_SHIFT),params.size); + EQ_((r_size >> TST_SECTOR_SHIFT),params.size); OK_(crypt_deactivate(cd,CDEVICE_1)); CRYPT_FREE(cd); - params.hash = "sha1"; + params.hash = "sha256"; params.offset = 0; params.size = 0; params.skip = 0; @@ -448,7 +459,7 @@ static void AddDevicePlain(void) // device status check GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); - snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1); + GE_(snprintf(path, sizeof(path), "%s/%s", crypt_get_dir(), CDEVICE_1), 0); fd = open(path, O_RDONLY); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_BUSY); FAIL_(crypt_deactivate(cd, CDEVICE_1), "Device is busy"); @@ -487,6 +498,7 @@ static void AddDevicePlain(void) // crypt_set_data_device FAIL_(crypt_set_data_device(cd,H_DEVICE),"can't set data device for plain device"); NULL_(crypt_get_metadata_device_name(cd)); + FAIL_(crypt_header_is_detached(cd), "plain has no header"); // crypt_get_type OK_(strcmp(crypt_get_type(cd),CRYPT_PLAIN)); @@ -495,18 +507,18 @@ static void AddDevicePlain(void) GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); // crypt_resize() - OK_(crypt_resize(cd,CDEVICE_1,size>>SECTOR_SHIFT)); // same size + OK_(crypt_resize(cd, CDEVICE_1, size >> TST_SECTOR_SHIFT)); // same size if (!t_device_size(path,&r_size)) EQ_(r_size, size); // size overlaps FAIL_(crypt_resize(cd, CDEVICE_1, (uint64_t)-1),"Backing device is too small"); - FAIL_(crypt_resize(cd, CDEVICE_1, (size>>SECTOR_SHIFT)+1),"crypt device overlaps backing device"); + FAIL_(crypt_resize(cd, CDEVICE_1, (size >> TST_SECTOR_SHIFT) + 1),"crypt device overlaps backing device"); // resize ok OK_(crypt_resize(cd,CDEVICE_1, 123)); if (!t_device_size(path,&r_size)) - EQ_(r_size>>SECTOR_SHIFT, 123); + EQ_(r_size >> TST_SECTOR_SHIFT, 123); OK_(crypt_resize(cd,CDEVICE_1,0)); // full size (autodetect) if (!t_device_size(path,&r_size)) EQ_(r_size, size); @@ -517,20 +529,20 @@ static void AddDevicePlain(void) // offset tests OK_(crypt_init(&cd,DEVICE_1)); params.offset = 42; - params.size = (size>>SECTOR_SHIFT) - params.offset - 10; + params.size = (size >> TST_SECTOR_SHIFT) - params.offset - 10; OK_(crypt_format(cd,CRYPT_PLAIN,cipher,cipher_mode,NULL,NULL,key_size,¶ms)); OK_(crypt_activate_by_volume_key(cd,CDEVICE_1,key,key_size,0)); if (!t_device_size(path,&r_size)) - EQ_(r_size>>SECTOR_SHIFT, params.size); + EQ_(r_size >> TST_SECTOR_SHIFT, params.size); // resize to fill remaining capacity OK_(crypt_resize(cd,CDEVICE_1,params.size + 10)); if (!t_device_size(path,&r_size)) - EQ_(r_size>>SECTOR_SHIFT, params.size + 10); + EQ_(r_size >> TST_SECTOR_SHIFT, params.size + 10); // 1 sector beyond real size 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_(r_size >> TST_SECTOR_SHIFT, params.size + 10); GE_(crypt_status(cd,CDEVICE_1),CRYPT_ACTIVE); fd = open(path, O_RDONLY); NOTFAIL_(fd, "Bad loop device."); @@ -539,11 +551,11 @@ static void AddDevicePlain(void) // resize to minimal size OK_(crypt_resize(cd,CDEVICE_1, 1)); // minimal device size if (!t_device_size(path,&r_size)) - EQ_(r_size>>SECTOR_SHIFT, 1); + EQ_(r_size >> TST_SECTOR_SHIFT, 1); // use size of backing device (autodetect with respect to offset) OK_(crypt_resize(cd,CDEVICE_1,0)); if (!t_device_size(path,&r_size)) - EQ_(r_size>>SECTOR_SHIFT, (size >> SECTOR_SHIFT)- 42); + EQ_(r_size >> TST_SECTOR_SHIFT, (size >> TST_SECTOR_SHIFT)- 42); OK_(crypt_deactivate(cd,CDEVICE_1)); CRYPT_FREE(cd); @@ -567,6 +579,11 @@ static void AddDevicePlain(void) key_size++; OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key2, &key_size, passphrase, strlen(passphrase))); OK_(memcmp(key, key2, key_size)); + memset(key2, 0, key_size); + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase, strlen(passphrase), &kc)); + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, kc)); + OK_(memcmp(key, key2, key_size)); + crypt_keyslot_context_free(kc); OK_(strcmp(cipher, crypt_get_cipher(cd))); OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); @@ -599,6 +616,9 @@ static void AddDevicePlain(void) FAIL_(crypt_keyslot_add_by_keyfile(cd,CRYPT_ANY_SLOT,KEYFILE1,strlen(KEY1),KEYFILE2,strlen(KEY2)),"can't add keyslot to plain device"); FAIL_(crypt_keyslot_destroy(cd,1),"can't manipulate keyslots on plain device"); EQ_(crypt_keyslot_status(cd, 0), CRYPT_SLOT_INVALID); + FAIL_(crypt_set_label(cd, "label", "subsystem"), "can't set labels for plain device"); + NULL_(crypt_get_label(cd)); + NULL_(crypt_get_subsystem(cd)); _remove_keyfiles(); CRYPT_FREE(cd); @@ -615,7 +635,7 @@ static void new_log(int level, const char *msg, void *usrptr) static void CallbacksTest(void) { struct crypt_params_plain params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, }; @@ -752,6 +772,10 @@ static void SuspendDevice(void) OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); + /* skip tests using empty passphrase */ + if(_fips_mode) + return; + 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)); @@ -786,17 +810,17 @@ static void AddDeviceLuks(void) }; char key[128], key2[128], key3[128]; - const char *passphrase = "blabla", *passphrase2 = "nsdkFI&Y#.sd"; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - const char *mk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; - size_t key_size = strlen(mk_hex) / 2; + const char *passphrase = PASSPHRASE, *passphrase2 = "nsdkFI&Y#.sd"; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset, r_header_size, r_size_1; struct crypt_pbkdf_type pbkdf; - crypt_decode_key(key, mk_hex, key_size); - crypt_decode_key(key3, mk_hex2, key_size); + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key3, vk_hex2, key_size); // init test devices OK_(get_luks_offsets(1, key_size, 0, 0, &r_header_size, &r_payload_offset)); @@ -877,7 +901,7 @@ static void AddDeviceLuks(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(t_device_size(DMDIR CDEVICE_1, &r_size_1)); - EQ_(r_size_1, SECTOR_SIZE); + EQ_(r_size_1, TST_SECTOR_SIZE); OK_(crypt_deactivate(cd, CDEVICE_1)); EQ_(crypt_status(cd, CDEVICE_1), CRYPT_INACTIVE); // restrict format only to empty context @@ -921,6 +945,7 @@ static void AddDeviceLuks(void) OK_(crypt_init(&cd, DMDIR L_DEVICE_1S)); OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); + EQ_(0, crypt_header_is_detached(cd)); CRYPT_FREE(cd); params.data_alignment = 0; params.data_device = DEVICE_2; @@ -935,6 +960,7 @@ static void AddDeviceLuks(void) FAIL_(crypt_activate_by_volume_key(cd, CDEVICE_2, key, key_size, 0), "Device is active"); EQ_(crypt_status(cd, CDEVICE_2), CRYPT_INACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(crypt_header_is_detached(cd), 1); CRYPT_FREE(cd); params.data_device = NULL; @@ -1023,11 +1049,16 @@ static void AddDeviceLuks(void) OK_(crypt_dump(cd)); OK_(!(global_lines != 0)); reset_log(); + FAIL_(crypt_dump_json(cd, NULL, 0), "LUKS1 not supported"); FAIL_(crypt_set_uuid(cd, "blah"), "wrong UUID format"); OK_(crypt_set_uuid(cd, DEVICE_TEST_UUID)); OK_(strcmp(DEVICE_TEST_UUID, crypt_get_uuid(cd))); + FAIL_(crypt_set_label(cd, "label", "subsystem"), "can't set labels for LUKS1 device"); + NULL_(crypt_get_label(cd)); + NULL_(crypt_get_subsystem(cd)); + FAIL_(crypt_deactivate(cd, CDEVICE_2), "not active"); CRYPT_FREE(cd); @@ -1063,9 +1094,9 @@ static void UseTempVolumes(void) // Dirty checks: device without UUID // we should be able to remove it but not manipulate with it - snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" + GE_(snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 " - "%s 2048\"", CDEVICE_2, DEVICE_2); + "%s 2048\"", CDEVICE_2, DEVICE_2), 0); _system(tmp, 1); OK_(crypt_init_by_name(&cd, CDEVICE_2)); OK_(crypt_deactivate(cd, CDEVICE_2)); @@ -1073,10 +1104,10 @@ static void UseTempVolumes(void) CRYPT_FREE(cd); // Dirty checks: device with UUID but LUKS header key fingerprint must fail) - snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" + GE_(snprintf(tmp, sizeof(tmp), "dmsetup create %s --table \"" "0 100 crypt aes-cbc-essiv:sha256 deadbabedeadbabedeadbabedeadbabe 0 " "%s 2048\" -u CRYPT-LUKS1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-ctest1", - CDEVICE_2, DEVICE_2); + CDEVICE_2, DEVICE_2), 0); _system(tmp, 1); OK_(crypt_init_by_name(&cd, CDEVICE_2)); OK_(crypt_deactivate(cd, CDEVICE_2)); @@ -1108,20 +1139,20 @@ static void LuksHeaderRestore(void) .data_alignment = 2048, // 4M, data offset will be 4096 }; struct crypt_params_plain pl_params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 }; char key[128], key2[128], cmd[256]; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 5000)); @@ -1146,7 +1177,7 @@ static void LuksHeaderRestore(void) FAIL_(crypt_header_restore(cd, CRYPT_LUKS1, EVL_HEADER_5), "Header corrupted"); OK_(crypt_header_restore(cd, CRYPT_LUKS1, VALID_HEADER)); // wipe valid luks header - snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=512 count=%" PRIu64 " 2>/dev/null", r_payload_offset); + GE_(snprintf(cmd, sizeof(cmd), "dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=512 count=%" PRIu64 " 2>/dev/null", r_payload_offset), 0); OK_(_system(cmd, 1)); FAIL_(crypt_header_restore(cd, CRYPT_LUKS1, EVL_HEADER_1), "Header corrupted"); FAIL_(crypt_header_restore(cd, CRYPT_LUKS1, EVL_HEADER_2), "Header corrupted"); @@ -1195,21 +1226,21 @@ static void LuksHeaderLoad(void) .data_alignment = 2048, }; struct crypt_params_plain pl_params = { - .hash = "sha1", + .hash = "sha256", .skip = 0, .offset = 0, .size = 0 }; char key[128], cmd[256]; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset, r_header_size; uint64_t mdata_size, keyslots_size; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); // prepare test env OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, &r_header_size, &r_payload_offset)); @@ -1218,8 +1249,8 @@ static void LuksHeaderLoad(void) // prepared header on a device too small to contain header and payload //OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, r_payload_offset - 1)); OK_(create_dmdevice_over_loop(H_DEVICE_WRONG, 2050 - 1)); //FIXME - //snprintf(cmd, sizeof(cmd), "dd if=" EVL_HEADER_4 " of=" DMDIR H_DEVICE_WRONG " bs=512 count=%" PRIu64, r_payload_offset - 1); - snprintf(cmd, sizeof(cmd), "dd if=" EVL_HEADER_4 " of=" DMDIR H_DEVICE_WRONG " bs=512 count=%d 2>/dev/null", 2050 - 1); + //GE_(snprintf(cmd, sizeof(cmd), "dd if=" EVL_HEADER_4 " of=" DMDIR H_DEVICE_WRONG " bs=512 count=%" PRIu64, r_payload_offset - 1), 0); + GE_(snprintf(cmd, sizeof(cmd), "dd if=" EVL_HEADER_4 " of=" DMDIR H_DEVICE_WRONG " bs=512 count=%d 2>/dev/null", 2050 - 1), 0); OK_(_system(cmd, 1)); // some device OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1000)); @@ -1242,6 +1273,7 @@ static void LuksHeaderLoad(void) 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)); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // repeat with init with two devices @@ -1252,6 +1284,7 @@ static void LuksHeaderLoad(void) OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(!crypt_get_metadata_device_name(cd)); EQ_(strcmp(DMDIR H_DEVICE, crypt_get_metadata_device_name(cd)), 0); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // bad header: device too small (payloadOffset > device_size) @@ -1268,7 +1301,7 @@ static void LuksHeaderLoad(void) FAIL_(crypt_set_metadata_size(cd, 0x004000, 0x004000), "Wrong context type"); OK_(crypt_get_metadata_size(cd, &mdata_size, &keyslots_size)); EQ_(mdata_size, LUKS_ALIGN_KEYSLOTS); - EQ_(keyslots_size, r_header_size * SECTOR_SIZE - mdata_size); + EQ_(keyslots_size, r_header_size * TST_SECTOR_SIZE - mdata_size); CRYPT_FREE(cd); // load should be ok OK_(crypt_init(&cd, DMDIR L_DEVICE_0S)); @@ -1312,15 +1345,15 @@ static void LuksHeaderBackup(void) char key[128]; int fd, ro = O_RDONLY; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset; const char *passphrase = PASSPHRASE; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_OK, r_payload_offset + 1)); @@ -1342,6 +1375,7 @@ static void LuksHeaderBackup(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(0, crypt_header_is_detached(cd)); CRYPT_FREE(cd); // exercise luksOpen using backup header in file @@ -1351,6 +1385,7 @@ static void LuksHeaderBackup(void) EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, 0, passphrase, strlen(passphrase), 0), 0); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); + EQ_(1, crypt_header_is_detached(cd)); CRYPT_FREE(cd); OK_(crypt_init(&cd, BACKUP_FILE)); @@ -1392,13 +1427,13 @@ static void ResizeDeviceLuks(void) }; char key[128]; - const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; - size_t key_size = strlen(mk_hex) / 2; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; const char *cipher = "aes"; const char *cipher_mode = "cbc-essiv:sha256"; uint64_t r_payload_offset, r_header_size, r_size; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); // prepare env OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); @@ -1414,14 +1449,14 @@ static void ResizeDeviceLuks(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); OK_(crypt_resize(cd, CDEVICE_1, 42)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(42, r_size >> SECTOR_SHIFT); + EQ_(42, r_size >> TST_SECTOR_SHIFT); // autodetect encrypted device area size OK_(crypt_resize(cd, CDEVICE_1, 0)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(1000, r_size >> SECTOR_SHIFT); + EQ_(1000, r_size >> TST_SECTOR_SHIFT); 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_(1000, r_size >> TST_SECTOR_SHIFT); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1434,14 +1469,14 @@ static void ResizeDeviceLuks(void) OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); OK_(crypt_resize(cd, CDEVICE_1, 666)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(666, r_size >> SECTOR_SHIFT); + EQ_(666, r_size >> TST_SECTOR_SHIFT); // autodetect encrypted device size OK_(crypt_resize(cd, CDEVICE_1, 0)); if (!t_device_size(DMDIR CDEVICE_1, &r_size)) - EQ_(1000, r_size >> SECTOR_SHIFT); + EQ_(1000, r_size >> TST_SECTOR_SHIFT); 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_(1000, r_size >> TST_SECTOR_SHIFT); GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1480,7 +1515,7 @@ static void HashDevicePlain(void) }; size_t key_size; - const char *mk_hex, *keystr; + const char *vk_hex, *keystr; char key[256]; OK_(crypt_init(&cd, DEVICE_1)); @@ -1493,41 +1528,41 @@ static void HashDevicePlain(void) // hash PLAIN, exact key // 0 1 2 3 4 5 6 7 8 9 a b c d e f - mk_hex = "caffeecaffeecaffeecaffeecaffee88"; + vk_hex = "caffeecaffeecaffeecaffeecaffee88"; key_size = 16; - crypt_decode_key(key, mk_hex, key_size); + crypt_decode_key(key, vk_hex, key_size); OK_(prepare_keyfile(KEYFILE1, key, key_size)); OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); // Limit plain key - mk_hex = "caffeecaffeecaffeecaffeeca000000"; + vk_hex = "caffeecaffeecaffeecaffeeca000000"; OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size - 3, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); _remove_keyfiles(); // hash PLAIN, long key // 0 1 2 3 4 5 6 7 8 9 a b c d e f - mk_hex = "caffeecaffeecaffeecaffeecaffee88babebabe"; + vk_hex = "caffeecaffeecaffeecaffeecaffee88babebabe"; key_size = 16; - crypt_decode_key(key, mk_hex, key_size); - OK_(prepare_keyfile(KEYFILE1, key, strlen(mk_hex) / 2)); + crypt_decode_key(key, vk_hex, key_size); + OK_(prepare_keyfile(KEYFILE1, key, strlen(vk_hex) / 2)); OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - FAIL_(strcmp(key, mk_hex), "only key length used"); - OK_(strncmp(key, mk_hex, key_size)); + FAIL_(strcmp(key, vk_hex), "only key length used"); + OK_(strncmp(key, vk_hex, key_size)); OK_(crypt_deactivate(cd, CDEVICE_1)); // Now without explicit limit OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - FAIL_(strcmp(key, mk_hex), "only key length used"); - OK_(strncmp(key, mk_hex, key_size)); + FAIL_(strcmp(key, vk_hex), "only key length used"); + OK_(strncmp(key, vk_hex, key_size)); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1536,15 +1571,15 @@ static void HashDevicePlain(void) // Handling of legacy "plain" hash (no hash) params.hash = "plain"; // 0 1 2 3 4 5 6 7 8 9 a b c d e f - mk_hex = "aabbcaffeecaffeecaffeecaffeecaff"; + vk_hex = "aabbcaffeecaffeecaffeecaffeecaff"; key_size = 16; - crypt_decode_key(key, mk_hex, key_size); - OK_(prepare_keyfile(KEYFILE1, key, strlen(mk_hex) / 2)); + crypt_decode_key(key, vk_hex, key_size); + OK_(prepare_keyfile(KEYFILE1, key, strlen(vk_hex) / 2)); OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_format(cd, CRYPT_PLAIN, "aes", "cbc-essiv:sha256", NULL, NULL, 16, ¶ms)); OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); @@ -1556,19 +1591,19 @@ static void HashDevicePlain(void) OK_(crypt_format(cd, CRYPT_PLAIN, "aes", "cbc-essiv:sha256", NULL, NULL, 16, ¶ms)); // 0 1 2 3 4 5 6 7 8 9 a b c d e f - mk_hex = "c62e4615bd39e222572f3a1bf7c2132e"; + vk_hex = "c62e4615bd39e222572f3a1bf7c2132e"; keystr = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; key_size = strlen(keystr); // 32 OK_(prepare_keyfile(KEYFILE1, keystr, strlen(keystr))); OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); // Read full keyfile OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); _remove_keyfiles(); @@ -1578,7 +1613,7 @@ static void HashDevicePlain(void) OK_(prepare_keyfile(KEYFILE1, keystr, strlen(keystr))); OK_(crypt_activate_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, key_size, 0)); OK_(get_key_dm(CDEVICE_1, key, sizeof(key))); - OK_(strcmp(key, mk_hex)); + OK_(strcmp(key, vk_hex)); OK_(crypt_deactivate(cd, CDEVICE_1)); // Full keyfile @@ -1690,6 +1725,10 @@ static void VerityTest(void) OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, root_hash_out, &root_hash_out_size, NULL, 0)); EQ_(32, root_hash_out_size); OK_(memcmp(root_hash, root_hash_out, root_hash_out_size)); + memset(root_hash_out, 0, root_hash_out_size); + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, root_hash_out, &root_hash_out_size, NULL)); + EQ_(32, root_hash_out_size); + OK_(memcmp(root_hash, root_hash_out, root_hash_out_size)); OK_(crypt_deactivate(cd, CDEVICE_1)); /* hash fail */ @@ -1730,7 +1769,7 @@ static void TcryptTest(void) const char *tcrypt_dev = "tcrypt-images/tck_5-sha512-xts-aes"; const char *tcrypt_dev2 = "tcrypt-images/tc_5-sha512-xts-serpent-twofish-aes"; size_t key_size = 64; - char key[key_size], key_def[key_size]; + char key[64], key_def[64]; const char *key_hex = "98dee64abe44bbf41d171c1f7b3e8eacda6d6b01f459097459a167f8c2872a96" "3979531d1cdc18af62757cf22286f16f8583d848524f128d7594ac2082668c73"; @@ -1766,6 +1805,9 @@ static void TcryptTest(void) key_size++; OK_(crypt_volume_key_get(cd, CRYPT_ANY_SLOT, key, &key_size, NULL, 0)); OK_(memcmp(key, key_def, key_size)); + memset(key, 0, key_size); + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key, &key_size, NULL)); + OK_(memcmp(key, key_def, key_size)); reset_log(); OK_(crypt_dump(cd)); @@ -1780,6 +1822,7 @@ static void TcryptTest(void) 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"); + FAIL_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key, &key_size, NULL), "Need crypt_load"); // check params after init_by_name OK_(strcmp("xts-plain64", crypt_get_cipher_mode(cd))); @@ -1824,6 +1867,150 @@ static void TcryptTest(void) EQ_(crypt_status(NULL, CDEVICE_1 "_1"), CRYPT_INACTIVE); } +static void ResizeIntegrity(void) +{ + struct crypt_params_integrity params = { + .tag_size = 4, + .integrity = "crc32c", + .sector_size = 4096, + }; + int ret; + uint64_t r_size, whole_device_size = 0; + + if (!t_dm_integrity_resize_support()) { + printf("WARNING: integrity device resize not supported, skipping test.\n"); + return; + } + + OK_(crypt_init(&cd, DEVICE_2)); + ret = crypt_format(cd,CRYPT_INTEGRITY,NULL,NULL,NULL,NULL,0,¶ms); + if (ret < 0) { + printf("WARNING: cannot format integrity device, skipping test.\n"); + CRYPT_FREE(cd); + return; + } + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, NULL, 0, 0)); + t_device_size(DMDIR CDEVICE_1, &whole_device_size); + // shrink the device + OK_(crypt_resize(cd, CDEVICE_1, 1024 * 1024 / 512)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(1024 * 1024 / 512, r_size >> TST_SECTOR_SHIFT); + FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); + // fill the whole device again (size = 0) + OK_(crypt_resize(cd, CDEVICE_1, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(whole_device_size, r_size); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + + // detached metadata + OK_(create_dmdevice_over_loop(H_DEVICE, 1024 * 1024 / 512)); + OK_(crypt_init_data_device(&cd, DMDIR H_DEVICE, DEVICE_2)); + OK_(crypt_format(cd,CRYPT_INTEGRITY,NULL,NULL,NULL,NULL,0,¶ms)); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, NULL, 0, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &whole_device_size)) + EQ_(10 * 1024 * 1024 / 512, whole_device_size >> TST_SECTOR_SHIFT); + // shrink the device + OK_(crypt_resize(cd, CDEVICE_1, 1024 * 1024 / 512)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(1024 * 1024 / 512, r_size >> TST_SECTOR_SHIFT); + FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); + // fill the whole device again (size = 0) + OK_(crypt_resize(cd, CDEVICE_1, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(whole_device_size, r_size); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + + _cleanup_dmdevices(); +} + +static void ResizeIntegrityWithKey(void) +{ + struct crypt_params_integrity params = { + .tag_size = 4, + .integrity = "hmac(sha256)", + .journal_integrity = "hmac(sha256)", + .journal_crypt = "cbc(aes)", + .sector_size = 4096, + }; + int ret; + uint64_t r_size, whole_device_size = 0; + + const char *key_integrity_hex = "41b06f3968ff10783edf3dd8c31d0d6e"; + const char *key_journal_integrity_hex = "9a3f924d03ab4a3307b148f844628f59"; + const char *key_journal_crypt_hex = "087a6943383f6c344cef03695b4f7277"; + + char integrity_key[128], journal_integrity_key[128], journal_crypt_key[128]; + + size_t integrity_key_size = strlen(key_integrity_hex) / 2; + size_t journal_integrity_key_size = strlen(key_journal_integrity_hex) / 2; + size_t journal_crypt_key_size = strlen(key_journal_crypt_hex) / 2; + + crypt_decode_key(integrity_key, key_integrity_hex, integrity_key_size); + crypt_decode_key(journal_integrity_key, key_journal_integrity_hex, journal_integrity_key_size); + crypt_decode_key(journal_crypt_key, key_journal_crypt_hex, journal_crypt_key_size); + + params.integrity_key_size = integrity_key_size; + + params.journal_integrity_key_size = journal_integrity_key_size; + params.journal_integrity_key = journal_integrity_key; + + params.journal_crypt_key_size = journal_crypt_key_size; + params.journal_crypt_key = journal_crypt_key; + + if (!t_dm_integrity_resize_support()) { + printf("WARNING: integrity device resize not supported, skipping test.\n"); + return; + } + + OK_(crypt_init(&cd, DEVICE_2)); + ret = crypt_format(cd,CRYPT_INTEGRITY,NULL,NULL,NULL,NULL,0,¶ms); + if (ret < 0) { + printf("WARNING: cannot format integrity device, skipping test.\n"); + CRYPT_FREE(cd); + return; + } + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, integrity_key, integrity_key_size, 0)); + t_device_size(DMDIR CDEVICE_1, &whole_device_size); + // shrink the device + OK_(crypt_resize(cd, CDEVICE_1, 1024*1024/512)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(1024*1024/512, r_size >> TST_SECTOR_SHIFT); + FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); + // fill the whole device again (size = 0) + OK_(crypt_resize(cd, CDEVICE_1, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(whole_device_size, r_size); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + + // detached metadata + OK_(create_dmdevice_over_loop(H_DEVICE, 1024 * 1024 / 512)); + OK_(crypt_init_data_device(&cd, DMDIR H_DEVICE, DEVICE_2)); + OK_(crypt_format(cd,CRYPT_INTEGRITY,NULL,NULL,NULL,NULL,0,¶ms)); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, integrity_key, integrity_key_size, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &whole_device_size)) + EQ_(10*1024*1024/512, whole_device_size >> TST_SECTOR_SHIFT); + // shrink the device + OK_(crypt_resize(cd, CDEVICE_1, 1024*1024/512)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(1024*1024/512, r_size >> TST_SECTOR_SHIFT); + FAIL_(crypt_resize(cd, CDEVICE_1, 1001), "Device too small"); + // fill the whole device again (size = 0) + OK_(crypt_resize(cd, CDEVICE_1, 0)); + if (!t_device_size(DMDIR CDEVICE_1, &r_size)) + EQ_(whole_device_size, r_size); + GE_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE); + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + + _cleanup_dmdevices(); +} + static void IntegrityTest(void) { struct crypt_params_integrity params = { @@ -1831,6 +2018,7 @@ static void IntegrityTest(void) .integrity = "crc32c", .sector_size = 4096, }, ip = {}; + struct crypt_active_device cad; int ret; // FIXME: this should be more detailed @@ -1850,6 +2038,7 @@ static void IntegrityTest(void) EQ_(ip.interleave_sectors, params.interleave_sectors); EQ_(ip.journal_size, params.journal_size); EQ_(ip.journal_watermark, params.journal_watermark); + EQ_(ip.integrity_key_size, 0); OK_(strcmp(ip.integrity,params.integrity)); FAIL_(crypt_set_uuid(cd,DEVICE_1_UUID),"can't set uuid to integrity device"); CRYPT_FREE(cd); @@ -1873,10 +2062,253 @@ static void IntegrityTest(void) EQ_(ip.tag_size, params.tag_size); OK_(strcmp(ip.integrity,params.integrity)); OK_(strcmp(CRYPT_INTEGRITY,crypt_get_type(cd))); + + if (t_dm_integrity_recalculate_support()) { + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(cad.flags & CRYPT_ACTIVATE_RECALCULATE, 0); + OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, NULL, 0, CRYPT_ACTIVATE_REFRESH | CRYPT_ACTIVATE_RECALCULATE)); + OK_(crypt_get_active_device(cd, CDEVICE_1, &cad)); + EQ_(cad.flags & CRYPT_ACTIVATE_RECALCULATE, CRYPT_ACTIVATE_RECALCULATE); + } + OK_(crypt_deactivate(cd, CDEVICE_1)); CRYPT_FREE(cd); } +static void WipeTest(void) +{ + OK_(crypt_init(&cd, NULL)); + FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL), "No device"); + FAIL_(crypt_wipe(cd, DEVICE_WRONG, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL), "Wrong device"); + OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL)); + OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_RANDOM, 0, 4096, 0, 0, NULL, NULL)); + OK_(crypt_wipe(cd, DEVICE_1, CRYPT_WIPE_RANDOM, 0, 4096, 0, CRYPT_WIPE_NO_DIRECT_IO, NULL, NULL)); + CRYPT_FREE(cd); + + OK_(crypt_init(&cd, DEVICE_1)); + OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 4096, 0, 0, NULL, NULL)); + OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096, TST_SECTOR_SIZE, 0, NULL, NULL)); + FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096, TST_SECTOR_SIZE-1, 0, NULL, NULL), "Sector size"); + FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 0, 4096 - 1, 0, 0, NULL, NULL), "Length size not aligned"); + FAIL_(crypt_wipe(cd, NULL, CRYPT_WIPE_RANDOM, 1, 4096, 0, 0, NULL, NULL), "Offset not aligned"); + CRYPT_FREE(cd); +} + +static void LuksKeyslotAdd(void) +{ + enum { OFFSET_1M = 2048 , OFFSET_2M = 4096, OFFSET_4M = 8192, OFFSET_8M = 16384 }; + struct crypt_params_luks1 params = { + .hash = "sha512", + .data_alignment = OFFSET_1M, // 4M, data offset will be 4096 + }; + struct crypt_pbkdf_type min_pbkdf2 = { + .type = "pbkdf2", + .hash = "sha256", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK + }; + char key[128], key3[128]; + + const char *passphrase = PASSPHRASE, *passphrase2 = "nsdkFI&Y#.sd"; + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + const char *vk_hex2 = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1e"; + size_t key_size = strlen(vk_hex) / 2; + const char *cipher = "aes"; + const char *cipher_mode = "cbc-essiv:sha256"; + uint64_t r_payload_offset; + struct crypt_keyslot_context *um1, *um2; + + crypt_decode_key(key, vk_hex, key_size); + crypt_decode_key(key3, vk_hex2, key_size); + + // init test devices + OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(H_DEVICE, r_payload_offset + 1)); + + // test support for embedded key (after crypt_format) + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, NULL, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase, strlen(passphrase), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 3, um2, 0), 3); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + CRYPT_FREE(cd); + + // test add by volume key + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase2, strlen(passphrase2), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, CRYPT_ANY_SLOT, um2, 0), 0); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // Add by same passphrase + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase, strlen(passphrase), &um1)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 1, um1, 0), 1); + crypt_keyslot_context_free(um1); + + // new passphrase can't be provided by key method + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase, strlen(passphrase), &um1)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, 1, um1, CRYPT_ANY_SLOT, um2, 0), "Can't get passphrase via selected unlock method"); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // add by keyfile + OK_(prepare_keyfile(KEYFILE1, passphrase2, strlen(passphrase2))); + OK_(prepare_keyfile(KEYFILE2, KEY1, strlen(KEY1))); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, 0, um1, 2, um2, 0), 2); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // add by same keyfile + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um1)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 4, um1, 0), 4); + crypt_keyslot_context_free(um1); + + // keyslot already exists + OK_(crypt_keyslot_context_init_by_passphrase(cd, passphrase2, strlen(passphrase2), &um1)); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, 3, um1, 0, um2, 0), "Keyslot already exists."); + crypt_keyslot_context_free(um2); + + // flags not supported with LUKS1 + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, CRYPT_ANY_SLOT, um2, CRYPT_VOLUME_KEY_NO_SEGMENT), "Not supported with LUKS1."); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + // LUKS2 token not supported + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um1)); + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, 2, um1, CRYPT_ANY_SLOT, um2, 0), "Not supported with LUKS1."); + EQ_(crypt_keyslot_context_get_error(um2), -EINVAL); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE2, 0, 0, &um1)); + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um2)); + FAIL_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um2, CRYPT_ANY_SLOT, um1, 0), "Not supported with LUKS1."); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + + CRYPT_FREE(cd); + + _cleanup_dmdevices(); +} + +static void VolumeKeyGet(void) +{ + struct crypt_params_luks1 params = { + .hash = "sha512", + .data_alignment = 2048, // 2M, data offset will be 2048 + }; + struct crypt_pbkdf_type min_pbkdf2 = { + .type = "pbkdf2", + .hash = "sha256", + .iterations = 1000, + .flags = CRYPT_PBKDF_NO_BENCHMARK + }; + char key[128], key2[128]; + + const char *vk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(vk_hex) / 2; + const char *cipher = "aes"; + const char *cipher_mode = "cbc-essiv:sha256"; + uint64_t r_payload_offset; + struct crypt_keyslot_context *um1, *um2; + + crypt_decode_key(key, vk_hex, key_size); + + OK_(prepare_keyfile(KEYFILE1, PASSPHRASE1, strlen(PASSPHRASE1))); + + // init test devices + OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); + OK_(create_dmdevice_over_loop(H_DEVICE, r_payload_offset + 1)); + + // test support for embedded key (after crypt_format) + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + key_size--; + FAIL_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL), "buffer too small"); + + // check cached generated volume key can be retrieved + key_size++; + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL)); + OK_(crypt_volume_key_verify(cd, key2, key_size)); + CRYPT_FREE(cd); + + // check we can add keyslot via retrieved key + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key2, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 3, um2, 0), 3); + crypt_keyslot_context_free(um1); + crypt_keyslot_context_free(um2); + CRYPT_FREE(cd); + + // check selected volume key can be retrieved and added + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_set_pbkdf_type(cd, &min_pbkdf2)); + OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + memset(key2, 0, key_size); + OK_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, NULL)); + OK_(memcmp(key, key2, key_size)); + OK_(crypt_keyslot_context_init_by_volume_key(cd, key2, key_size, &um1)); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 0, um2, 0), 0); + crypt_keyslot_context_free(um2); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um2)); + EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, um1, 1, um2, 0), 1); + crypt_keyslot_context_free(um2); + crypt_keyslot_context_free(um1); + CRYPT_FREE(cd); + + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); + // check key context is not usable + OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), -EINVAL); + crypt_keyslot_context_free(um1); + + // check token context is not usable + OK_(crypt_keyslot_context_init_by_token(cd, CRYPT_ANY_TOKEN, NULL, NULL, 0, NULL, &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), -EINVAL); + crypt_keyslot_context_free(um1); + + // by passphrase + memset(key2, 0, key_size); + OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), 0); + OK_(memcmp(key, key2, key_size)); + memset(key2, 0, key_size); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, 0, key2, &key_size, um1), 0); + OK_(memcmp(key, key2, key_size)); + crypt_keyslot_context_free(um1); + + // by keyfile + memset(key2, 0, key_size); + OK_(crypt_keyslot_context_init_by_keyfile(cd, KEYFILE1, 0, 0, &um1)); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, CRYPT_ANY_SLOT, key2, &key_size, um1), 1); + OK_(memcmp(key, key2, key_size)); + memset(key2, 0, key_size); + EQ_(crypt_volume_key_get_by_keyslot_context(cd, 1, key2, &key_size, um1), 1); + crypt_keyslot_context_free(um1); + CRYPT_FREE(cd); + + _remove_keyfiles(); + _cleanup_dmdevices(); +} + // Check that gcrypt is properly initialised in format static void NonFIPSAlg(void) { @@ -1968,6 +2400,11 @@ int main(int argc, char *argv[]) RUN_(VerityTest, "DM verity"); RUN_(TcryptTest, "Tcrypt API"); RUN_(IntegrityTest, "Integrity API"); + RUN_(ResizeIntegrity, "Integrity raw resize"); + RUN_(ResizeIntegrityWithKey, "Integrity raw resize with key"); + RUN_(WipeTest, "Wipe device"); + RUN_(LuksKeyslotAdd, "Adding keyslot via new API"); + RUN_(VolumeKeyGet, "Getting volume key via keyslot context API"); _cleanup(); return 0; diff --git a/tests/api_test.h b/tests/api_test.h index 91b47b7..14efead 100644 --- a/tests/api_test.h +++ b/tests/api_test.h @@ -1,9 +1,9 @@ /* * cryptsetup library API check functions * - * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2021 Milan Broz - * Copyright (C) 2016-2021 Ondrej Kozina + * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2023 Milan Broz + * Copyright (C) 2016-2023 Ondrej Kozina * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,6 +38,10 @@ int t_dm_check_versions(void); int t_dm_crypt_keyring_support(void); int t_dm_crypt_cpu_switch_support(void); int t_dm_crypt_discard_support(void); +int t_dm_integrity_resize_support(void); +int t_dm_integrity_recalculate_support(void); +int t_dm_capi_string_supported(void); +int t_set_readahead(const char *device, unsigned value); int fips_mode(void); @@ -96,9 +100,14 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch #define CRYPT_FREE(x) do { crypt_free(x); x = NULL; } while (0) -#define SECTOR_SHIFT 9L -#define SECTOR_SIZE 512 -#define TST_LOOP_FILE_SIZE (((1<<20)*100)>>SECTOR_SHIFT) +/* to silent clang -Wcast-align when working with byte arrays */ +#define VOIDP_CAST(x) (x)(void*) + +#define DMDIR "/dev/mapper/" + +#define TST_SECTOR_SHIFT 9L +#define TST_SECTOR_SIZE 512 +#define TST_LOOP_FILE_SIZE (((1 << 20) * 100) >> TST_SECTOR_SHIFT) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define DIV_ROUND_UP_MODULO(n,d) (DIV_ROUND_UP(n,d)*(d)) @@ -116,7 +125,23 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch #define T_DM_VERITY_FEC_SUPPORTED (1 << 10) /* Forward Error Correction (FEC) */ #define T_DM_KERNEL_KEYRING_SUPPORTED (1 << 11) /* dm-crypt allows loading kernel keyring keys */ #define T_DM_INTEGRITY_SUPPORTED (1 << 12) /* dm-integrity target supported */ -//FIXME add T_DM_SECTOR_SIZE once we have version +#define T_DM_SECTOR_SIZE_SUPPORTED (1 << 13) /* support for sector size setting in dm-crypt/dm-integrity */ +#define T_DM_CAPI_STRING_SUPPORTED (1 << 14) /* support for cryptoapi format cipher definition */ +#define T_DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */ +#define T_DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */ +#define T_DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */ +#define T_DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */ +#define T_DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */ +#define T_DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */ +#define T_DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */ +#define T_DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */ +#define T_DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */ +#define T_DM_INTEGRITY_RESIZE_SUPPORTED (1 << 23) /* dm-integrity resize of the integrity device supported (introduced in the same version as discards)*/ +#define T_DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */ +#define T_DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */ +#define T_DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */ +#define T_DM_INTEGRITY_RESET_RECALC_SUPPORTED (1 << 27) /* dm-integrity automatic recalculation supported */ +#define T_DM_VERITY_TASKLETS_SUPPORTED (1 << 28) /* dm-verity tasklets supported */ /* loop helpers */ int loop_device(const char *loop); @@ -124,4 +149,17 @@ int loop_attach(char **loop, const char *file, int offset, int autoclear, int *readonly); int loop_detach(const char *loop); +int t_device_size_by_devno(dev_t devno, uint64_t *retval); +int t_get_devno(const char *dev, dev_t *devno); + +typedef enum { ERR_RD = 0, ERR_WR, ERR_RW, ERR_REMOVE } error_io_info; + +int dmdevice_error_io(const char *dm_name, + const char *dm_device, + const char *error_device, + uint64_t data_offset, + uint64_t offset, + uint64_t length, + error_io_info ei); + #endif diff --git a/tests/bitlk-compat-test b/tests/bitlk-compat-test index c8210b5..8559e06 100755 --- a/tests/bitlk-compat-test +++ b/tests/bitlk-compat-test @@ -6,6 +6,7 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup TST_DIR=bitlk-images MAP=bitlktst +DUMP_VK_FILE=bitlk-test-vk CRYPTSETUP_VALGRIND=../.libs/cryptsetup CRYPTSETUP_LIB_VALGRIND=../.libs @@ -15,6 +16,7 @@ CRYPTSETUP_LIB_VALGRIND=../.libs function remove_mapping() { [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP + rm -rf $TST_DIR } function fail() @@ -31,56 +33,65 @@ function skip() { [ -n "$1" ] && echo "$1" echo "Test skipped." + remove_mapping exit 77 } function load_vars() { - local file=$(echo $1 | sed -e s/^$TST_DIR\\/// | sed -e s/\.img$//) - source <(grep = <(grep -A8 "\[$file\]" $TST_DIR/images.conf)) + local file=$(echo $1 | sed -e s/^$TST_DIR\\/// | sed -e s/\.img$//) + source <(grep = <(grep -A8 "\[$file\]" $TST_DIR/images.conf)) } function check_dump() { - dump=$1 - file=$2 - - # load variables for this image from config file - load_vars $file - - # GUID - dump_guid=$(echo "$dump" | grep Version -A 1 | tail -1 | cut -d: -f2 | tr -d "\t\n ") - [ ! -z "$GUID" -a "$dump_guid" = "$GUID" ] || fail " GUID check from dump failed." - - # cipher - dump_cipher=$(echo "$dump" | grep "Cipher name" | cut -d: -f2 | tr -d "\t\n ") - dump_mode=$(echo "$dump" | grep "Cipher mode" | cut -d: -f2 | tr -d "\t\n ") - cipher=$(echo "$dump_cipher-$dump_mode") - [ ! -z "$CIPHER" -a "$cipher" = "$CIPHER" ] || fail " cipher check from dump failed." - - if echo "$file" | grep -q -e "smart-card"; then - # 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." + dump=$1 + file=$2 + + # load variables for this image from config file + load_vars $file + + # volume size + dump_size=$(echo "$dump" | grep "Volume size:" | cut -d: -f2 | tr -d "\t\n ") + [ "$dump_size" = "104857600[bytes]" -o "$dump_size" = "134217728[bytes]" ] || fail " volume size check from dump failed." + + # description + dump_desc=$(echo "$dump" | grep Description: | cut -d: -f2 | tr -d "\t\n ") + [ "${dump_desc:0:7}" = "DESKTOP" -o "${dump_desc:0:3}" = "WIN" ] || fail " Description check from dump failed." + + # GUID + dump_guid=$(echo "$dump" | grep Version -A 1 | tail -1 | cut -d: -f2 | tr -d "\t\n ") + [ ! -z "$GUID" -a "$dump_guid" = "$GUID" ] || fail " GUID check from dump failed." + + # cipher + dump_cipher=$(echo "$dump" | grep "Cipher name" | cut -d: -f2 | tr -d "\t\n ") + dump_mode=$(echo "$dump" | grep "Cipher mode" | cut -d: -f2 | tr -d "\t\n ") + cipher=$(echo "$dump_cipher-$dump_mode") + [ ! -z "$CIPHER" -a "$cipher" = "$CIPHER" ] || fail " cipher check from dump failed." + + if echo "$file" | grep -q -e "smart-card"; then + # 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 ") - [ ! -z "$PW_VMK_GUID" -a "$dump_pw_vmk" = "$PW_VMK_GUID" ] || fail " password protected VMK GUID check from dump failed." - fi - - # recovery password protected VMK GUID - dump_rp_vmk=$(echo "$dump" | grep "VMK protected with recovery passphrase" -B 1 | head -1 | cut -d: -f2 | tr -d "\t ") - [ ! -z "$RP_VMK_GUID" -a "$dump_rp_vmk" = "$RP_VMK_GUID" ] || fail " recovery password protected VMK GUID check from dump failed." + # 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 ") + [ ! -z "$PW_VMK_GUID" -a "$dump_pw_vmk" = "$PW_VMK_GUID" ] || fail " password protected VMK GUID check from dump failed." + fi + + # recovery password protected VMK GUID + dump_rp_vmk=$(echo "$dump" | grep "VMK protected with recovery passphrase" -B 1 | head -1 | cut -d: -f2 | tr -d "\t ") + [ ! -z "$RP_VMK_GUID" -a "$dump_rp_vmk" = "$RP_VMK_GUID" ] || fail " recovery password protected VMK GUID check from dump failed." } function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } @@ -91,7 +102,8 @@ function valgrind_run() } export LANG=C -[ ! -d $TST_DIR ] && tar xJSf $srcdir/bitlk-images.tar.xz --no-same-owner +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ ! -d $TST_DIR ] && tar xJSf $srcdir/bitlk-images.tar.xz --no-same-owner 2>/dev/null || skip "Incompatible tar." [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run @@ -99,21 +111,20 @@ echo "HEADER CHECK" for file in $(ls $TST_DIR/bitlk-*) ; do echo -n " $file" out=$($CRYPTSETUP bitlkDump $file) - check_dump "$out" "$file" + check_dump "$out" "$file" echo " [OK]" done if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run activation part of test, test skipped." + remove_mapping exit 0 fi -remove_mapping - echo "ACTIVATION FS UUID CHECK" for file in $(ls $TST_DIR/bitlk-*) ; do # load variables for this image from config file - load_vars $file + load_vars $file # test with both passphrase and recovery passphrase for PASSPHRASE in $PW $RP ; do @@ -131,7 +142,7 @@ for file in $(ls $TST_DIR/bitlk-*) ; do [ $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) + uuid=$(blkid -p -o value -s UUID /dev/mapper/$MAP) sha256sum=$(sha256sum /dev/mapper/$MAP | cut -d" " -f1) $CRYPTSETUP remove $MAP || fail [ "$uuid" = "$UUID" ] || fail " UUID check failed." @@ -139,6 +150,30 @@ for file in $(ls $TST_DIR/bitlk-*) ; do echo " [OK]" done + # test with volume key + rm -f $DUMP_VK_FILE >/dev/null 2>&1 + echo -n " $file" + echo $PASSPHRASE | $CRYPTSETUP bitlkDump -r $file --dump-volume-key --volume-key-file $DUMP_VK_FILE >/dev/null 2>&1 + ret=$? + [ $ret -eq 0 ] || fail " failed to dump volume key" + $CRYPTSETUP bitlkOpen -r $file $MAP --volume-key-file $DUMP_VK_FILE >/dev/null 2>&1 + ret=$? + [ $ret -eq 1 ] && ( echo "$file" | grep -q -e "aes-cbc" ) && echo " [N/A]" && continue + [ $ret -eq 1 ] && ( echo "$file" | grep -q -e "aes-cbc-elephant" ) && echo " [N/A]" && continue + [ $ret -eq 1 ] && ( echo "$file" | grep -q -e "clearkey" ) && echo " [N/A]" && continue + [ $ret -eq 1 ] && ( echo "$file" | grep -q -e "eow" ) && echo " [N/A]" && continue + [ $ret -eq 1 ] && ( echo "$file" | grep -q -e "-4k.img" ) && echo " [N/A]" && continue + [ $ret -eq 0 ] || fail " failed to open $file using volume key ($ret)" + $CRYPTSETUP status $MAP >/dev/null || fail + $CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail + uuid=$(blkid -p -o value -s 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]" + rm -f $DUMP_VK_FILE >/dev/null 2>&1 + # startup key test -- we need to use BEK file from the archive if echo "$file" | grep -q -e "startup-key"; then echo -n " $file" @@ -151,7 +186,7 @@ for file in $(ls $TST_DIR/bitlk-*) ; do [ $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) + uuid=$(blkid -p -o value -s UUID /dev/mapper/$MAP) sha256sum=$(sha256sum /dev/mapper/$MAP | cut -d" " -f1) $CRYPTSETUP remove $MAP || fail [ "$uuid" = "$UUID" ] || fail " UUID check failed." @@ -160,3 +195,6 @@ for file in $(ls $TST_DIR/bitlk-*) ; do fi done + +remove_mapping +exit 0 diff --git a/tests/bitlk-images.tar.xz b/tests/bitlk-images.tar.xz Binary files differindex eea33ed..845e9de 100644 --- a/tests/bitlk-images.tar.xz +++ b/tests/bitlk-images.tar.xz diff --git a/tests/blockwise-compat b/tests/blockwise-compat-test index a764020..11db493 100755 --- a/tests/blockwise-compat +++ b/tests/blockwise-compat-test @@ -14,14 +14,14 @@ scsi_debug_teardown() { local _tries=15; while [ -b "$1" -a $_tries -gt 0 ]; do - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 if [ -b "$1" ]; then sleep .1 _tries=$((_tries-1)) fi done - test ! -b "$1" || rmmod scsi_debug + test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } cleanup() { @@ -56,15 +56,19 @@ skip() { echo "TEST SKIPPED: $1" cleanup - exit 0 + exit 77 } add_device() { - modprobe scsi_debug $@ delay=0 + rmmod scsi_debug >/dev/null 2>&1 + if [ -d /sys/module/scsi_debug ] ; then + skip "Cannot use scsi_debug module (in use or compiled-in)." + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 + skip "This kernel seems to not support proper scsi_debug module." fi + grep -q scsi_debug /sys/block/*/device/model || sleep 2 DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) DEV="/dev/$DEV" [ -b $DEV ] || fail "Cannot find $DEV." @@ -76,24 +80,24 @@ falloc() { run_all_in_fs() { for file in $(ls img_fs_*.img.xz) ; do - echo "Run tests in $file put on top block device." - xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" - [ ! -d $MNT_DIR ] && mkdir $MNT_DIR - mount $DEV $MNT_DIR - if [ $? -ne 0 ]; then - echo "Mounting image $file failed, skipped." - continue; - fi - rm -rf $MNT_DIR/* 2>/dev/null - local tfile=$MNT_DIR/bwunit_tstfile - falloc $DEVSIZEMB $tfile || fail "enospc?" - local iobsize=$(stat -c "%o" $tfile) - test -n "$iobsize" -a $iobsize -gt 0 || fail - local oldbsize=$BSIZE - BSIZE=$iobsize - run_all $tfile - BSIZE=$oldbsize - umount $MNT_DIR + echo "Run tests in $file put on top block device." + xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image" + [ ! -d $MNT_DIR ] && mkdir $MNT_DIR + mount $DEV $MNT_DIR + if [ $? -ne 0 ]; then + echo "Mounting image $file failed, skipped." + continue; + fi + rm -rf $MNT_DIR/* 2>/dev/null + local tfile=$MNT_DIR/bwunit_tstfile + falloc $DEVSIZEMB $tfile || fail "enospc?" + local iobsize=$(stat -c "%o" $tfile) + test -n "$iobsize" -a $iobsize -gt 0 || fail + local oldbsize=$BSIZE + BSIZE=$iobsize + run_all $tfile + BSIZE=$oldbsize + umount $MNT_DIR done } @@ -116,8 +120,8 @@ RUN() { _fsize=$(stat -c "%s" $_dev) } - case "$_res" in - P) + case "$_res" in + P) MSG="Testing $_fn on $_type with params $@ [expecting TRUE]..." $BW_UNIT $_dev $_fn $@ if [ $? -ne 0 ]; then @@ -131,8 +135,8 @@ RUN() { else MSG="$MSG[OK]" fi - ;; - F) + ;; + F) MSG="Testing $_fn on $_type with params $@ [expecting FALSE]..." $BW_UNIT $_dev $_fn $@ 2> /dev/null if [ $? -eq 0 ]; then @@ -146,11 +150,11 @@ RUN() { else MSG="$MSG[OK]" fi - ;; - *) - fail "Internal test error" - ;; - esac + ;; + *) + fail "Internal test error" + ;; + esac trunc_file $_fsize $_dev } @@ -304,9 +308,7 @@ run_all() { RUN "$BD_FAIL" $1 write_lseek_blockwise $((BSIZE+1)) $BSIZE $((DEVSIZE-BSIZE)) } -[ -n "$CRYPTSETUP_PATH" ] && skip "Cannot run this test with CRYPTSETUP_PATH set." - -which $STRACE > /dev/null 2>&1 || unset STRACE +command -v $STRACE >/dev/null || unset STRACE test -x $BW_UNIT || skip "Run \"make `basename $BW_UNIT`\" first" FAILS=0 diff --git a/tests/compat-args-test b/tests/compat-args-test new file mode 100755 index 0000000..c41e942 --- /dev/null +++ b/tests/compat-args-test @@ -0,0 +1,299 @@ +#!/bin/bash + +PS4='$LINENO:' +[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + +TEST_UUID="12345678-1234-1234-1234-123456789abc" + +TFILE=test-args.out + +function cleanup() +{ + rm -f $TFILE 2> /dev/null +} + +function fail() +{ + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + cleanup + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + echo "Test skipped." + cleanup + exit 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +function xxx() +{ + $CRYPTSETUP --test-args $@ > $TFILE 2>&1 + local ret=$? + + grep -q -e ": unknown option\|Argument <action> missing" $TFILE && { + echo "'$CRYPTSETUP --test-args $@' command:" + cat $TFILE + fail "Probably typo in test" + } + test $ret -ne 0 || fail +} + +function exp_fail() +{ + # xxx $@ + $CRYPTSETUP --test-args $@ 2>/dev/null && fail +} + +function exp_pass() +{ + $CRYPTSETUP --test-args $@ >/dev/null || fail +} + +export LANG=C +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + +# initial test constructed according to current cryptsetup content +echo "[1] Current state" +exp_fail resize NAME --test-passphrase +exp_fail close NAME --test-passphrase +exp_pass open DEV NAME --test-passphrase --type bitlk +exp_pass open DEV NAME --test-passphrase --type luks +exp_pass open DEV NAME --test-passphrase --type luks1 +exp_pass open DEV NAME --test-passphrase --type luks2 +exp_fail open DEV NAME --test-passphrase --type plain + +exp_fail open DEV NAME --deferred +exp_pass close NAME --deferred + +exp_pass open DEV NAME --type plain --shared +exp_fail open DEV NAME --type luks1 --shared +exp_fail close NAME --shared + +exp_pass open DEV NAME --allow-discards +exp_fail close NAME --allow-discards + +exp_fail close NAME --persistent +exp_pass open DEV NAME --persistent +exp_fail open DEV NAME --persistent --test-passphrase + +exp_fail luksFormat DEV --serialize-memory-hard-pbkdf +exp_pass open DEV NAME --serialize-memory-hard-pbkdf + +exp_pass reencrypt DEV --key-size 32 +exp_fail reencrypt DEV --key-size 31 +exp_fail reencrypt DEV --key-size -32 +exp_pass luksFormat DEV --key-size 32 +exp_fail luksFormat DEV --key-size 31 +exp_fail luksFormat DEV --key-size -32 +exp_pass open DEV NAME --key-size 32 # --type plain -c aes-xts-plain64 +exp_fail open DEV NAME --key-size 31 # --type plain -c aes-xts-plain64 +exp_pass benchmark --key-size 32 +exp_fail benchmark --key-size 31 +exp_pass luksAddKey DEV --key-size 32 # --unbound +exp_fail luksAddKey DEV --key-size 31 # --unbound + +exp_fail close NAME --key-size 32 +exp_fail luksUUID DEV --key-size 32 + +# bug +# exp_fail luksFormat DEV --type luks1 --integrity hmac-sha256 +exp_pass luksFormat DEV --type luks2 --integrity hmac-sha256 +exp_fail open DEV NAME --integrity hmac-sha256 + +exp_pass luksFormat DEV --type luks2 --integrity hmac-sha256 --integrity-no-wipe +exp_fail luksFormat DEV --type luks2 --integrity-no-wipe +# bug +# exp_fail luksFormat DEV --type luks1 --integrity hmac-sha256 --integrity-no-wipe +exp_fail open DEV NAME --integrity-no-wipe +exp_fail open DEV NAME --integrity-no-wipe --integrity hmac-sha256 + +exp_pass luksFormat --label L --subsystem S DEV # --type luks2 +exp_pass luksFormat --label L DEV # --type luks2 +exp_pass luksFormat --subsystem S DEV # --type luks2 +exp_pass config --label L --subsystem S DEV +exp_pass config --label L DEV +exp_pass config --subsystem S DEV +# bug +#exp_fail luksFormat --label L --subsystem S DEV --type luks1 +#exp_fail luksFormat --label L DEV --type luks1 +#exp_fail luksFormat --subsystem S DEV --type luks1 +exp_fail open DEV NAME --label L --subsystem S +exp_fail open DEV NAME --label L +exp_fail open DEV NAME --subsystem S + +exp_fail luksFormat DEV -S-2 +# bug +# exp_fail luksFormat DEV -S-1 + +# prob. many bug: accepts --[new-]keyfile-size w/o --[new-]key-file +exp_pass luksFormat DEV --keyfile-size 42 --key-file F +exp_fail luksFormat DEV --keyfile-size -1 --key-file F +# bug (is it? e.g. empty passphrase) +# exp_fail luksFormat DEV --keyfile-size 0 +exp_pass luksAddKey DEV --keyfile-size 42 --key-file F --new-keyfile-size 42 NF +exp_fail luksAddKey DEV --new-keyfile-size -42 NF +exp_fail luksAddKey DEV --keyfile-size 42 --key-file F --new-keyfile-size -42 NF +exp_fail luksFormat DEV --keyfile-size -1 --key-file F +# bug (is it? e.g. empty passphrase) +# exp_fail luksFormat DEV --keyfile-size 0 + +exp_fail open DEV NAME --key-file F0 --key-file F1 +exp_pass open DEV NAME --key-file F0 --key-file F1 --type tcrypt + +# why? (luksAddKey fail) +exp_fail luksAddKey DEV --use-random +exp_fail luksAddKey DEV --use-urandom +exp_fail luksAddKey DEV --use-urandom --use-random +exp_fail luksFormat DEV --use-urandom --use-random +exp_pass luksFormat DEV --use-random +exp_pass luksFormat DEV --use-urandom + +exp_fail open DEV NAME --uuid $TEST_UUID +exp_pass luksFormat DEV --uuid $TEST_UUID +exp_pass luksUUID DEV --uuid $TEST_UUID + +exp_fail open DEV NAME --align-payload 8192 +exp_fail open DEV NAME --align-payload 8292 --type plain +exp_pass luksFormat DEV --align-payload 8192 +exp_fail luksFormat DEV --align-payload 8192 --offset 16384 +exp_fail luksFormat DEV --align-payload 8192 --offset 8192 + +exp_fail resize NAME --luks2-metadata-size 16k +exp_fail resize NAME --luks2-keyslots-size 16m +exp_pass luksFormat DEV --luks2-keyslots-size 16m +exp_pass luksFormat DEV --luks2-metadata-size 16k +exp_pass reencrypt DEV --luks2-keyslots-size 16m +exp_pass reencrypt DEV --luks2-metadata-size 16k + +exp_fail luksFormat DEV --skip 8192 +exp_fail open DEV NAME --skip 8192 +exp_pass open DEV NAME --skip 8192 --type plain +exp_pass open DEV NAME --skip 8192 --type loopaes + +exp_fail resize NAME --offset 8292 +exp_pass luksFormat DEV --offset 16384 +exp_fail open DEV NAME --offset 16384 +exp_pass open DEV NAME --offset 16384 --type plain +exp_pass open DEV NAME --offset 16384 --type loopaes + +exp_fail open DEV NAME --tcrypt-hidden +exp_fail open DEV NAME --tcrypt-system +exp_fail open DEV NAME --tcrypt-backup +# bug +# exp_fail open DEV NAME --tcrypt-hidden --tcrypt-system --tcrypt-backup --type tcrypt +exp_pass open DEV NAME --tcrypt-hidden --type tcrypt +exp_pass open DEV NAME --tcrypt-backup --type tcrypt +exp_pass open DEV NAME --tcrypt-system --type tcrypt +exp_pass tcryptDump DEV NAME --tcrypt-hidden --type tcrypt +exp_pass tcryptDump DEV NAME --tcrypt-backup --type tcrypt +exp_pass tcryptDump DEV NAME --tcrypt-system --type tcrypt +exp_fail tcryptDump DEV NAME --allow-discards --tcrypt-hidden --type tcrypt + +# bug +# exp_fail close NAME --type tcrypt --veracrypt +exp_fail open DEV NAME --veracrypt +exp_pass open DEV NAME --type tcrypt --veracrypt +exp_pass open DEV NAME --type tcrypt --veracrypt --veracrypt-pim 1 +exp_fail open DEV NAME --type tcrypt --veracrypt --veracrypt-pim -2 +exp_fail open DEV NAME --type tcrypt --disable-veracrypt --veracrypt-pim 1 +exp_fail open DEV NAME --type tcrypt --veracrypt --veracrypt-pim -1 +exp_fail open DEV NAME --type tcrypt --disable-veracrypt --veracrypt-query-pim +exp_fail open DEV NAME --type tcrypt --disable-veracrypt --veracrypt-query-pim --veracrypt-pim 1 +exp_fail open DEV NAME --disable-veracrypt --veracrypt-query-pim + +# bug +# exp_fail open DEV NAME --priority normal +exp_fail config DEV --priority normal +exp_fail config DEV -S1 --priority norma +exp_pass config DEV -S1 --priority normal +exp_pass config DEV -S1 --priority ignore +exp_pass config DEV -S1 --priority prefer + +# bug +# exp_fail open DEV NAME --pbkdf argon2i +exp_fail luksFormat DEV --pbkdf blah +exp_pass luksFormat DEV --pbkdf argon2i +exp_pass luksFormat DEV --pbkdf pbkdf2 +exp_pass luksFormat DEV --pbkdf argon2id +exp_fail luksFormat DEV --type luks2 --pbkdf-force-iterations 4 -i1 +exp_fail luksFormat DEV --type luks1 --pbkdf-force-iterations 1001 -i1 + +exp_fail open DEV NAME --sector-size 1024 +exp_pass open DEV NAME --type plain --sector-size 1024 +# bug +# exp_fail luksFormat DEV --sector-size 0 +exp_fail luksFormat DEV --sector-size 511 +exp_fail luksFormat DEV --sector-size 8192 +exp_pass reencrypt DEV --sector-size 1024 +exp_pass luksFormat DEV --sector-size 1024 + +exp_fail luksFormat DEV --iv-large-sectors +exp_fail open DEV --type tcrypt --iv-large-sectors +exp_fail open DEV --type plain --iv-large-sectors --sector-size 512 +exp_pass open DEV --type plain --iv-large-sectors --sector-size 1024 + +exp_fail luksAddKey DEV --unbound +exp_fail luksAddKey DEV --unbound --key-size 0 +exp_pass luksAddKey DEV --unbound --key-size 8 +exp_pass luksDump DEV --unbound -S5 +exp_fail luksDump DEV --unbound +exp_pass open DEV --unbound --test-passphrase +exp_pass open DEV --unbound --test-passphrase -S5 +exp_fail open DEV --unbound NAME +exp_fail open DEV --unbound -S5 NAME + +exp_fail resize NAME --refresh +exp_fail open DEV NAME --test-passphrase --refresh +exp_pass open DEV NAME --refresh +exp_pass refresh DEV NAME +exp_fail refresh DEV NAME --test-passphrase + +# bug +# exp_fail luksFormat DEV --reduce-device-size 64m +exp_fail reencrypt DEV --reduce-device-size 2G # max 1g +exp_fail reencrypt DEV --reduce-device-size $((64*1024*1024+1)) +exp_fail reencrypt DEV --reduce-device-size -64m +exp_pass reencrypt DEV --reduce-device-size 64m +exp_fail reencrypt DEV --reduce-device-size 64m --device-size 100g +# bugs +# exp_fail open DEV --decrypt --header H +# exp_fail open DEV --encrypt +# exp_fail open DEV NAME --device-size 32m +# exp_fail open DEV NAME --size 100 +exp_pass open DEV NAME --device-size 32m --type plain +exp_fail open DEV NAME --device-size $((32*1024*1024+1)) --type plain +exp_pass open DEV NAME --size 100 --type plain +exp_fail open DEV NAME --size 100 --device-size $((512*100)) --type plain +exp_fail reencrypt DEV --device-size $((32*1024*1024+1)) +exp_pass reencrypt DEV --device-size 32m + +exp_fail luksFormat DEV NAME --keyslot-cipher ks +exp_fail luksFormat DEV NAME --keyslot-key-size 32 +exp_pass luksFormat DEV NAME --keyslot-cipher ks --keyslot-key-size 32 +# bugs +# exp_fail open DEV NAME --keyslot-cipher ks --keyslot-key-size 32 +# exp_fail luksFormat --type luks1 DEV NAME --keyslot-cipher ks --keyslot-key-size 32 + +cleanup +exit 0 diff --git a/tests/compat-test b/tests/compat-test index 6059880..6dc8004 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -8,6 +8,7 @@ CRYPTSETUP_RAW=$CRYPTSETUP CRYPTSETUP_VALGRIND=../.libs/cryptsetup CRYPTSETUP_LIB_VALGRIND=../.libs +DIFFER=./differ DEV_NAME=dummy DEV_NAME2=dummy2 DEV_NAME3=dummy3 @@ -44,7 +45,7 @@ KEY_MATERIAL5_EXT="S331776-395264" TEST_UUID="12345678-1234-1234-1234-123456789abc" LOOPDEV=$(losetup -f 2>/dev/null) -[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) function remove_mapping() { @@ -53,7 +54,7 @@ function remove_mapping() [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1 losetup -d $LOOPDEV >/dev/null 2>&1 rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $VK_FILE missing-file >/dev/null 2>&1 - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 scsi_debug_teardown $DEV } @@ -79,7 +80,7 @@ function fips_mode() function can_fail_fips() { - # Ignore this fail if running in FIPS mode + # Ignore this fail if running in FIPS mode fips_mode || fail $1 } @@ -87,7 +88,7 @@ function skip() { [ -n "$1" ] && echo "$1" remove_mapping - [ -z "$2" ] && exit $2 + [ -n "$2" ] && exit $2 exit 77 } @@ -127,8 +128,8 @@ function prepare() if [ ! -e $KEY1 ]; then #dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 - echo -n $'\x48\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$KEY1 - echo -n $'\x9c\x03\x5e\x1b\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$KEY1 + echo -n $'\x48\xc6\x74\x4f\x41\x4e\x50\xc0\x79\xc2\x2d\x5b\x5f\x68\x84\x17' >$KEY1 + echo -n $'\x9c\x03\x5e\x1b\x4d\x0f\x9a\x75\xb3\x90\x70\x32\x0a\xf8\xae\xc4'>>$KEY1 fi if [ ! -e $KEY2 ]; then @@ -151,7 +152,7 @@ function check() { sync [ -z "$1" ] && return - ./differ $ORIG_IMG $IMG $1 || fail + $DIFFER $ORIG_IMG $IMG $1 || fail } function check_exists() @@ -165,33 +166,37 @@ scsi_debug_teardown() { local _tries=15; while [ -b "$1" -a $_tries -gt 0 ]; do - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 if [ -b "$1" ]; then sleep .1 _tries=$((_tries-1)) fi done - test ! -b "$1" || rmmod scsi_debug 2> /dev/null + test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } function add_scsi_device() { scsi_debug_teardown $DEV - modprobe scsi_debug $@ delay=0 - if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 - fi - - sleep 1 - DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) - [ -b $DEV ] || fail "Cannot find $DEV." + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 77 + fi + + sleep 1 + DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $DEV ] || fail "Cannot find $DEV." } function valgrind_setup() { [ -n "$VALG" ] || return - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" CRYPTSETUP=valgrind_run @@ -211,6 +216,8 @@ function expect_run() } export LANG=C + +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." valgrind_setup # LUKS non-root-tests @@ -280,12 +287,16 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --uuid $TEST echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG -d $KEY1 || fail $CRYPTSETUP luksDump $IMG | grep -q "Key Slot 0: ENABLED" || fail $CRYPTSETUP luksDump $IMG | grep -q $TEST_UUID || fail +echo $PWDW | $CRYPTSETUP luksDump $IMG --dump-volume-key 2>/dev/null && fail echo $PWDW | $CRYPTSETUP luksDump $IMG --dump-master-key 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksDump $IMG --dump-volume-key | grep -q "MK dump:" || fail echo $PWD1 | $CRYPTSETUP luksDump $IMG --dump-master-key | grep -q "MK dump:" || fail -$CRYPTSETUP luksDump -q $IMG --dump-master-key -d $KEY1 | grep -q "MK dump:" || fail +$CRYPTSETUP luksDump -q $IMG --dump-volume-key -d $KEY1 | grep -q "MK dump:" || fail echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE >/dev/null || fail -echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $IMG || fail +rm -f $VK_FILE +echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail +echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-volume-key --volume-key-file $VK_FILE 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE $IMG || fail echo "[10] uuid" echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --uuid $TEST_UUID $IMG || fail @@ -293,13 +304,14 @@ $CRYPTSETUP -q luksUUID $IMG | grep -q $TEST_UUID || fail [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ -z "$LOOPDEV" ] && skip "WARNING: Cannot find free loop device, test skipped." +[ ! -x "$DIFFER" ] && skip "Cannot find $DIFFER, test skipped." # LUKS root-tests prepare "[1] open - compat image - acceptance check" new echo $PWD0 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail check_exists -ORG_SHA1=$(sha1sum -b /dev/mapper/$DEV_NAME | cut -f 1 -d' ') -[ "$ORG_SHA1" = 676062b66ebf36669dab705442ea0762dfc091b0 ] || fail +ORG_SHA256=$(sha256sum -b /dev/mapper/$DEV_NAME | cut -f 1 -d' ') +[ "$ORG_SHA256" = 7428e8f2436882a07eb32765086f5c899474c08b5576f556b573d2aabdf923e8 ] || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail # Check it can be opened from header backup as well @@ -311,6 +323,7 @@ $CRYPTSETUP -q luksClose $DEV_NAME || fail $CRYPTSETUP luksHeaderRestore -q $IMG --header-backup-file $HEADER_IMG || fail # Repeat for V1.0 header - not aligned first keyslot +if [ ! fips_mode ] ; then echo $PWD0 | $CRYPTSETUP luksOpen $IMG10 $DEV_NAME || fail check_exists ORG_SHA1=$(sha1sum -b /dev/mapper/$DEV_NAME | cut -f 1 -d' ') @@ -322,6 +335,7 @@ $CRYPTSETUP luksHeaderBackup $IMG10 --header-backup-file $HEADER_IMG echo $PWD0 | $CRYPTSETUP luksOpen $IMG10 $DEV_NAME --header $HEADER_IMG || fail check_exists $CRYPTSETUP -q luksClose $DEV_NAME || fail +fi prepare "[2] open - compat image - denial check" new echo $PWDW | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME 2>/dev/null && fail @@ -424,39 +438,44 @@ tst=$($CRYPTSETUP -q luksUUID $LOOPDEV) [ "$tst"x = "$TEST_UUID"x ] || fail prepare "[16] luksFormat" wipe -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --master-key-file /dev/urandom $LOOPDEV || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --master-key-file /dev/urandom $LOOPDEV -d $KEY1 || fail -$CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --master-key-file /dev/urandom -s 256 --uuid $TEST_UUID $LOOPDEV $KEY1 || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --volume-key-file /dev/urandom $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --volume-key-file /dev/urandom $LOOPDEV -d $KEY1 || fail +$CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --volume-key-file /dev/urandom -s 256 --uuid $TEST_UUID $LOOPDEV $KEY1 || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail # open by UUID -force_uevent # some systems do not update loop by-uuid -$CRYPTSETUP luksOpen -d $KEY1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail -$CRYPTSETUP luksOpen -d $KEY1 UUID=$TEST_UUID $DEV_NAME || fail -$CRYPTSETUP -q luksClose $DEV_NAME || fail +if [ -d /dev/disk/by-uuid ] ; then + force_uevent # some systems do not update loop by-uuid + $CRYPTSETUP luksOpen -d $KEY1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail + $CRYPTSETUP luksOpen -d $KEY1 UUID=$TEST_UUID $DEV_NAME || fail + $CRYPTSETUP -q luksClose $DEV_NAME || fail +fi +# skip tests using empty passphrase +if [ ! fips_mode ]; then # empty keyfile $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEYE || fail $CRYPTSETUP luksOpen -d $KEYE $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail +fi # open by volume key -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT -s 256 --master-key-file $KEY1 $LOOPDEV || fail -$CRYPTSETUP luksOpen --master-key-file /dev/urandom $LOOPDEV $DEV_NAME 2>/dev/null && fail -$CRYPTSETUP luksOpen --master-key-file $KEY1 $LOOPDEV $DEV_NAME || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT -s 256 --volume-key-file $KEY1 $LOOPDEV || fail +$CRYPTSETUP luksOpen --volume-key-file /dev/urandom $LOOPDEV $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP luksOpen --volume-key-file $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail # unsupported pe-keyslot encryption echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT -s 128 --keyslot-cipher "aes-cbc-plain" $LOOPDEV 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT -s 128 --keyslot-key-size 256 $LOOPDEV 2>/dev/null && fail prepare "[17] AddKey volume key, passphrase and keyfile" wipe -# masterkey -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/zero --key-slot 3 || fail +# volumekey +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/zero --key-slot 3 || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: ENABLED" || fail -echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/zero --key-slot 4 || fail +echo $PWD2 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/zero --key-slot 4 || fail echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 4 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 4: ENABLED" || fail -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/null --key-slot 5 2>/dev/null && fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/zero --key-slot 5 $KEY1 || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/null --key-slot 5 2>/dev/null && fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/zero --key-slot 5 $KEY1 || fail $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 5 -d $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail @@ -473,28 +492,28 @@ echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV -d $KEY1 -d $KEY1 --test-passphrase 2 # [0]PWD1 [1]PWD2 [2]$KEY1/1 [3]$KEY1 [4]$KEY2 $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEY1 --key-slot 3 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: ENABLED" || fail -$CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail +$CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail # keyfile/keyfile -$CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 4 || fail +$CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 4 || fail $CRYPTSETUP luksOpen $LOOPDEV -d $KEY2 --test-passphrase --key-slot 4 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 4: ENABLED" || fail # passphrase/keyfile -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 --key-slot 0 || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 --key-slot 0 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: ENABLED" || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 0 || fail # passphrase/passphrase -echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-slot 1 || fail +echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --key-slot 1 || fail echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail # keyfile/passphrase -echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 3 || fail +echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 8 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 2: ENABLED" || fail prepare "[18] RemoveKey passphrase and keyfile" reuse $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: DISABLED" || fail $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY1 2>/dev/null && fail -$CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 --key-slot 3 2>/dev/null || fail +$CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 --key-slot 3 2>/dev/null || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 3: ENABLED" || fail $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY2 --keyfile-size 1 2>/dev/null && fail $CRYPTSETUP luksRemoveKey $LOOPDEV $KEY2 || fail @@ -520,7 +539,7 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: DISABLED" || fail prepare "[19] create & status & resize" wipe echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash xxx 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --cipher aes-cbc-essiv:sha256 --offset 3 --skip 4 --readonly || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --cipher aes-cbc-essiv:sha256 --offset 3 --skip 4 --readonly || fail $CRYPTSETUP -q status $DEV_NAME | grep "offset:" | grep -q "3 sectors" || fail $CRYPTSETUP -q status $DEV_NAME | grep "skipped:" | grep -q "4 sectors" || fail $CRYPTSETUP -q status $DEV_NAME | grep "mode:" | grep -q "readonly" || fail @@ -540,15 +559,15 @@ $CRYPTSETUP -q resize $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "32765 sectors" || fail $CRYPTSETUP -q remove $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME >/dev/null && fail -echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $LOOPDEV || fail $CRYPTSETUP -q remove $DEV_NAME || fail -echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha1 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha256 $LOOPDEV || fail $CRYPTSETUP -q remove $DEV_NAME || fail -echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha1 --size 100 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q create $DEV_NAME --hash sha256 --size 100 $LOOPDEV || fail $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail $CRYPTSETUP -q remove $DEV_NAME || fail # 4k sector resize (if kernel supports it) -echo $PWD1 | $CRYPTSETUP -q open --type plain $LOOPDEV $DEV_NAME --sector-size 4096 --size 8 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP -q open --type plain --hash sha256 $LOOPDEV $DEV_NAME --sector-size 4096 --size 8 >/dev/null 2>&1 if [ $? -eq 0 ] ; then $CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "8 sectors" || fail $CRYPTSETUP -q resize $DEV_NAME --size 16 || fail @@ -561,7 +580,7 @@ if [ $? -eq 0 ] ; then fi # Resize not aligned to logical block size add_scsi_device dev_size_mb=32 sector_size=4096 -echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $DEV || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $DEV || fail OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') $CRYPTSETUP resize $DEV_NAME -b 7 2> /dev/null && fail dmsetup info $DEV_NAME | grep -q SUSPENDED && fail @@ -569,10 +588,10 @@ NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+ test $OLD_SIZE -eq $NEW_SIZE || fail $CRYPTSETUP close $DEV_NAME || fail # Add check for unaligned plain crypt activation -echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $DEV -b 7 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $DEV -b 7 2>/dev/null && fail $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail # verify is ignored on non-tty input -echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --verify-passphrase 2>/dev/null || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --verify-passphrase 2>/dev/null || fail $CRYPTSETUP -q remove $DEV_NAME || fail $CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 --key-size 255 2>/dev/null && fail $CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 --key-size -1 2>/dev/null && fail @@ -600,11 +619,11 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --uuid $TEST echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 0: ENABLED" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail -echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || fail -$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || fail -echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE > /dev/null || fail -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $LOOPDEV || fail +echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-volume-key 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-volume-key | grep -q "MK dump:" || fail +$CRYPTSETUP luksDump -q $LOOPDEV --dump-volume-key -d $KEY1 | grep -q "MK dump:" || fail +echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-volume-key --volume-key-file $VK_FILE > /dev/null || fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE $LOOPDEV || fail prepare "[22] remove disappeared device" wipe dmsetup create $DEV_NAME --table "0 5000 linear $LOOPDEV 2" || fail @@ -619,7 +638,7 @@ dmsetup remove --retry $DEV_NAME || fail prepare "[23] ChangeKey passphrase and keyfile" wipe # [0]$KEY1 [1]key0 $CRYPTSETUP -q luksFormat --type luks1 $LOOPDEV $KEY1 $FAST_PBKDF_OPT --key-slot 0 || fail -echo $PWD1 | $CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 --key-slot 1 || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 --key-slot 1 || fail # keyfile [0] / keyfile [0] $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 0 || fail # passphrase [1] / passphrase [1] @@ -689,15 +708,15 @@ $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d /dev/mapper/$DEV_NAME2 \ dmsetup remove --retry $DEV_NAME2 prepare "[25] Create shared segments" wipe -echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha1 --offset 0 --size 256 || fail -echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha1 --offset 512 --size 256 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha1 --offset 512 --size 256 --shared || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME $LOOPDEV --hash sha256 --offset 0 --size 256 || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha256 --offset 512 --size 256 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME2 $LOOPDEV --hash sha256 --offset 512 --size 256 --shared || fail $CRYPTSETUP -q remove $DEV_NAME2 || fail $CRYPTSETUP -q remove $DEV_NAME || fail prepare "[26] Suspend/Resume" wipe # only LUKS is supported -echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha1 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP create $DEV_NAME --hash sha256 $LOOPDEV || fail $CRYPTSETUP luksSuspend $DEV_NAME 2>/dev/null && fail $CRYPTSETUP luksResume $DEV_NAME 2>/dev/null && fail $CRYPTSETUP -q remove $DEV_NAME || fail @@ -712,14 +731,17 @@ 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 +# skip tests using empty passphrase +if [ ! fips_mode ]; then 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 +fi -prepare "[27] luksOpen with specified key slot number" wipe +prepare "[27] luksOpen/luksResume with specified key slot number" wipe # first, let's try passphrase option echo $PWD3 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT -S 5 $LOOPDEV || fail check $LUKS_HEADER $KEY_SLOT5 $KEY_MATERIAL5 @@ -727,8 +749,12 @@ echo $PWD3 | $CRYPTSETUP luksOpen -S 4 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail echo $PWD3 | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME || fail check_exists +$CRYPTSETUP luksSuspend $DEV_NAME || fail +echo $PWD3 | $CRYPTSETUP luksResume -S 4 $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +echo $PWD3 | $CRYPTSETUP luksResume -S 5 $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail -echo -e "$PWD3\n$PWD1" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 0 $LOOPDEV || fail +echo -e "$PWD3\n$PWD1" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 0 $LOOPDEV || fail check $LUKS_HEADER $KEY_SLOT0 $KEY_MATERIAL0 echo $PWD3 | $CRYPTSETUP luksOpen -S 0 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail @@ -737,10 +763,14 @@ echo $PWD1 | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME 2>/dev/null && fail # second, try it with keyfiles $CRYPTSETUP luksFormat --type luks1 -q -S 5 -d $KEY5 $LOOPDEV || fail check $LUKS_HEADER $KEY_SLOT5 $KEY_MATERIAL5 -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail check $LUKS_HEADER $KEY_SLOT1 $KEY_MATERIAL1 $CRYPTSETUP luksOpen -S 5 -d $KEY5 $LOOPDEV $DEV_NAME || fail check_exists +$CRYPTSETUP luksSuspend $DEV_NAME || fail +$CRYPTSETUP luksResume -S 1 -d $KEY5 $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +$CRYPTSETUP luksResume -S 5 -d $KEY5 $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail $CRYPTSETUP luksOpen -S 1 -d $KEY5 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail @@ -770,7 +800,7 @@ $CRYPTSETUP luksSuspend $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 +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail $CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "Key Slot 5: ENABLED" || fail $CRYPTSETUP luksKillSlot -q _fakedev_ --header $HEADER_IMG 5 || fail $CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "Key Slot 5: DISABLED" || fail @@ -784,10 +814,21 @@ $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME >/dev/null 2>&1 && fail $CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail +# fix ecb-plain +$CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEY1 --hash sha256 -c aes-ecb || fail +echo -n "ecb-xxx" | dd of=$LOOPDEV bs=1 seek=40 >/dev/null 2>&1 +$CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail +$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail +$CRYPTSETUP luksClose $DEV_NAME || fail +# fix uppercase hash +echo -n "SHA256" | dd of=$LOOPDEV bs=1 seek=72 >/dev/null 2>&1 +$CRYPTSETUP -q repair $LOOPDEV >/dev/null 2>&1 || fail +$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail +$CRYPTSETUP luksClose $DEV_NAME || fail prepare "[30] LUKS erase" wipe $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV $KEY5 --key-slot 5 || fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail $CRYPTSETUP luksErase -q $LOOPDEV || fail @@ -801,23 +842,25 @@ $CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 && fail $CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 || fail $CRYPTSETUP close --deferred $DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then - dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail - $CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 || fail - $CRYPTSETUP close $DEV_NAME2 || fail - $CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 && fail + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail + $CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 || fail + $CRYPTSETUP close --cancel-deferred $DEV_NAME >/dev/null 2>&1 + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" >/dev/null 2>&1 && fail + $CRYPTSETUP close --deferred $DEV_NAME >/dev/null 2>&1 + $CRYPTSETUP close $DEV_NAME2 || fail + $CRYPTSETUP -q status $DEV_NAME >/dev/null 2>&1 && fail else - $CRYPTSETUP close $DEV_NAME2 >/dev/null 2>&1 - $CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 + $CRYPTSETUP close $DEV_NAME2 >/dev/null 2>&1 + $CRYPTSETUP close $DEV_NAME >/dev/null 2>&1 fi # Interactive tests # Do not remove sleep 0.1 below, the password query flushes TTY buffer (so the code is racy). -which expect >/dev/null 2>&1 || skip "WARNING: expect tool missing, interactive test will be skipped." 0 +command -v expect >/dev/null || skip "WARNING: expect tool missing, interactive test will be skipped." 0 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_TIMEOUT=60 expect_run - >/dev/null <<EOF proc abort {} { send_error "Timeout. "; exit 2 } @@ -947,7 +990,7 @@ sleep 0.1 send "$PWD1\n" expect timeout abort "Command successful." expect timeout abort eof -eval spawn $CRYPTSETUP_RAW luksOpen $FAST_PBKDF_OPT -v $LOOPDEV --test-passphrase +eval spawn $CRYPTSETUP_RAW luksOpen -v $LOOPDEV --test-passphrase expect timeout abort "Enter passphrase" sleep 0.1 send "$PWD1\n" @@ -1061,5 +1104,34 @@ expect timeout abort eof EOF [ $? -eq 0 ] || fail "Expect script failed." +prepare "[41] New luksAddKey options." file +rm -f $VK_FILE +echo "$PWD1" | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $IMG || fail +echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail + +# pass pass +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q -S1 $FAST_PBKDF_OPT $IMG || fail +echo $PWD2 | $CRYPTSETUP open -q --test-passphrase -S1 $IMG || fail + +# pass file +echo "$PWD2" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S1 --new-key-slot 2 $IMG $KEY1 || fail +$CRYPTSETUP open --test-passphrase -q -S2 -d $KEY1 $IMG || fail + +# file pass +echo "$PWD3" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 -d $KEY1 --new-key-slot 3 $IMG || fail +echo $PWD3 | $CRYPTSETUP open -q --test-passphrase -S3 $IMG || fail + +# file file +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 --new-key-slot 4 -d $KEY1 --new-keyfile $KEY2 $IMG || fail +$CRYPTSETUP open --test-passphrase -q -S4 -d $KEY2 $IMG || fail + +# vk pass +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S5 --volume-key-file $VK_FILE $IMG || fail +echo $PWD3 | $CRYPTSETUP open -q --test-passphrase -S5 $IMG || fail + +# vk file +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S6 --volume-key-file $VK_FILE --new-keyfile $KEY5 $IMG || fail +$CRYPTSETUP open --test-passphrase -q -S6 -d $KEY5 $IMG || fail + remove_mapping exit 0 diff --git a/tests/compat-test2 b/tests/compat-test2 index 1612569..c54dc7e 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -42,7 +42,7 @@ FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" TEST_UUID="12345678-1234-1234-1234-123456789abc" LOOPDEV=$(losetup -f 2>/dev/null) -[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) function remove_mapping() { @@ -56,7 +56,7 @@ function remove_mapping() [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null unset TEST_KEYRING - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 scsi_debug_teardown $DEV } @@ -82,7 +82,7 @@ function fips_mode() function can_fail_fips() { - # Ignore this fail if running in FIPS mode + # Ignore this fail if running in FIPS mode fips_mode || fail $1 } @@ -152,7 +152,7 @@ function check_exists() function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } @@ -217,7 +217,7 @@ function dm_crypt_sector_size_support() } function test_and_prepare_keyring() { - which keyctl > /dev/null 2>&1 || skip "Cannot find keyctl, test skipped" + command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped" keyctl list "@s" > /dev/null || skip "Current session keyring is unreachable, test skipped" TEST_KEYRING=$(keyctl newring $TEST_KEYRING_NAME "@u" 2> /dev/null) test -n "$TEST_KEYRING" || skip "Failed to create keyring in user keyring" @@ -244,6 +244,11 @@ function setup_luks2_env() { else HAVE_KEYRING=0 fi + if $($CRYPTSETUP --version | grep -q "BLKID"); then + HAVE_BLKID=1 + else + HAVE_BLKID=0 + fi $CRYPTSETUP close $DEV_NAME || fail } @@ -252,31 +257,36 @@ scsi_debug_teardown() { local _tries=15; while [ -b "$1" -a $_tries -gt 0 ]; do - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 if [ -b "$1" ]; then sleep .1 _tries=$((_tries-1)) fi done - test ! -b "$1" || rmmod scsi_debug 2> /dev/null + test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } function add_scsi_device() { scsi_debug_teardown $DEV - modprobe scsi_debug $@ delay=0 - if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 - fi - - sleep 1 - DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) - [ -b $DEV ] || fail "Cannot find $DEV." + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 77 + fi + + sleep 1 + DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $DEV ] || fail "Cannot find $DEV." } export LANG=C +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ -z "$LOOPDEV" ] && skip "WARNING: Cannot find free loop device, test skipped." @@ -317,6 +327,8 @@ echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 -s 128 luksF prepare "[4] format using hash sha512" wipe echo $PWD1 | $CRYPTSETUP $FAST_PBKDF_OPT -h sha512 -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 $LOOPDEV || fail $CRYPTSETUP -q luksDump $LOOPDEV | grep "0: pbkdf2" -A2 | grep "Hash:" | grep -qe sha512 || fail +# Check JSON dump for some mandatory section +$CRYPTSETUP -q luksDump $LOOPDEV --dump-json-metadata | grep -q '"tokens":' || fail prepare "[5] open" echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME --test-passphrase || fail @@ -403,36 +415,42 @@ tst=$($CRYPTSETUP -q luksUUID $LOOPDEV) [ "$tst"x = "$TEST_UUID"x ] || fail prepare "[16] luksFormat" wipe -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --master-key-file /dev/urandom --type luks2 $LOOPDEV || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --master-key-file /dev/urandom --type luks2 $LOOPDEV -d $KEY1 || fail -$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --master-key-file /dev/urandom -s 256 --uuid $TEST_UUID --type luks2 $LOOPDEV $KEY1 || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --type luks2 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom --type luks2 $LOOPDEV -d $KEY1 || fail +$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --volume-key-file /dev/urandom -s 256 --uuid $TEST_UUID --type luks2 $LOOPDEV $KEY1 || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail # open by UUID -force_uevent # some systems do not update loop by-uuid -$CRYPTSETUP luksOpen -d $KEY1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail -$CRYPTSETUP luksOpen -d $KEY1 UUID=$TEST_UUID $DEV_NAME || fail -$CRYPTSETUP -q luksClose $DEV_NAME || fail +if [ -d /dev/disk/by-uuid ] ; then + force_uevent # some systems do not update loop by-uuid + $CRYPTSETUP luksOpen -d $KEY1 UUID=X$TEST_UUID $DEV_NAME 2>/dev/null && fail + $CRYPTSETUP luksOpen -d $KEY1 UUID=$TEST_UUID $DEV_NAME || fail + $CRYPTSETUP -q luksClose $DEV_NAME || fail +fi +# skip tests using empty passphrases +if [ ! fips_mode ]; then # empty keyfile $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEYE || fail $CRYPTSETUP luksOpen -d $KEYE $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail +fi + # open by volume key -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -s 256 --master-key-file $KEY1 --type luks2 $LOOPDEV || fail -$CRYPTSETUP luksOpen --master-key-file /dev/urandom $LOOPDEV $DEV_NAME 2>/dev/null && fail -$CRYPTSETUP luksOpen --master-key-file $KEY1 $LOOPDEV $DEV_NAME || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -s 256 --volume-key-file $KEY1 --type luks2 $LOOPDEV || fail +$CRYPTSETUP luksOpen --volume-key-file /dev/urandom $LOOPDEV $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP luksOpen --volume-key-file $KEY1 $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail prepare "[17] AddKey volume key, passphrase and keyfile" wipe -# masterkey -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --master-key-file /dev/zero --key-slot 3 || fail +# volumekey +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --volume-key-file /dev/zero --key-slot 3 || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2" || fail -echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/zero --key-slot 4 || fail +echo $PWD2 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/zero --key-slot 4 || fail echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 4 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "4: luks2" || fail -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/null --key-slot 5 2>/dev/null && fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --master-key-file /dev/zero --key-slot 5 $KEY1 || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/null --key-slot 5 2>/dev/null && fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --volume-key-file /dev/zero --key-slot 5 $KEY1 || fail $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 5 -d $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail @@ -449,21 +467,21 @@ echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV -d $KEY1 -d $KEY1 --test-passphrase 2 # [0]PWD1 [1]PWD2 [2]$KEY1/1 [3]$KEY1 [4]$KEY2 $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY1 --key-slot 3 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2" || fail -$CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail +$CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 3 2>/dev/null && fail # keyfile/keyfile -$CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 4 || fail +$CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 4 || fail $CRYPTSETUP luksOpen $LOOPDEV -d $KEY2 --test-passphrase --key-slot 4 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "4: luks2" || fail # passphrase/keyfile -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 --key-slot 0 || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 --key-slot 0 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 0 || fail # passphrase/passphrase -echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-slot 1 || fail +echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --key-slot 1 || fail echo $PWD2 | $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail # keyfile/passphrase -echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 3 || fail +echo -e "$PWD2\n" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV $KEY1 --key-slot 2 --new-keyfile-size 8 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" || fail prepare "[18] RemoveKey passphrase and keyfile" reuse @@ -543,10 +561,10 @@ $CRYPTSETUP close $DEV_NAME || fail add_scsi_device dev_size_mb=32 sector_size=4096 echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $DEV || fail echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail -OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') +OLD_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') #' echo $PWD1 | $CRYPTSETUP resize $DEV_NAME -b 7 2> /dev/null && fail dmsetup info $DEV_NAME | grep -q SUSPENDED && fail -NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') +NEW_SIZE=$($CRYPTSETUP status $DEV_NAME | grep "^ \+size:" | sed 's/.* \([0-9]\+\) .*/\1/') #' test $OLD_SIZE -eq $NEW_SIZE || fail $CRYPTSETUP close $DEV_NAME || fail @@ -564,16 +582,18 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --key-size 256 $FAST_PBKDF_OPT --uuid $TE echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail -echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || fail -$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || fail +echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-volume-key 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-volume-key | grep -q "MK dump:" || fail +$CRYPTSETUP luksDump -q $LOOPDEV --dump-volume-key -d $KEY1 | grep -q "MK dump:" || fail echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE >/dev/null || fail -echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $LOOPDEV || fail +rm -f $VK_FILE +echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail +echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-volume-key --volume-key-file $VK_FILE 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE $LOOPDEV || fail # Use volume key file without keyslots $CRYPTSETUP luksErase -q $LOOPDEV || fail -$CRYPTSETUP luksOpen --master-key-file $VK_FILE --key-size 256 --test-passphrase $LOOPDEV || fail -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE --key-size 256 $LOOPDEV || fail +$CRYPTSETUP luksOpen --volume-key-file $VK_FILE --key-size 256 --test-passphrase $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --volume-key-file $VK_FILE --key-size 256 $LOOPDEV || fail echo $PWD1 | $CRYPTSETUP luksOpen --test-passphrase $LOOPDEV || fail prepare "[22] remove disappeared device" wipe @@ -588,29 +608,24 @@ dmsetup remove --retry $DEV_NAME || fail prepare "[23] ChangeKey passphrase and keyfile" wipe # [0]$KEY1 [1]key0 -$CRYPTSETUP -q luksFormat --type luks2 $LOOPDEV $KEY1 $FAST_PBKDF_OPT --key-slot 0 || fail -echo $PWD1 | $CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 --key-slot 1 || fail +$CRYPTSETUP -q luksFormat --type luks2 $LOOPDEV $KEY1 $FAST_PBKDF_OPT --key-slot 0 --key-size 256 --luks2-keyslots-size 256k >/dev/null || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 --key-slot 1 || fail # keyfile [0] / keyfile [0] $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 --key-slot 0 || fail # passphrase [1] / passphrase [1] echo -e "$PWD1\n$PWD2\n" | $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT --key-slot 1 || fail -# keyfile [0] / keyfile [new] +# keyfile [0] / keyfile [new] - with LUKS2 it should stay $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 || fail -$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" && fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" && fail # passphrase [1] / passphrase [new] echo -e "$PWD2\n$PWD1\n" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT $LOOPDEV || fail -$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" && fail -# use all slots -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT || fail -# still allows replace -#FIXME -#$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 || fail -#$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 2>/dev/null && fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2" && fail +# test out of raw area, change in-place (space only for 2 keyslots) +$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 || fail +$CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail +$CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY1 $KEY2 2>/dev/null && fail prepare "[24] Keyfile limit" wipe $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY1 --key-slot 0 -l 13 || fail @@ -669,24 +684,32 @@ $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 +prepare "[27] luksOpen/Resume with specified key slot number" wipe # first, let's try passphrase option echo $PWD3 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT -S 5 --type luks2 $LOOPDEV || fail echo $PWD3 | $CRYPTSETUP luksOpen -S 4 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail echo $PWD3 | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME || fail check_exists +$CRYPTSETUP luksSuspend $DEV_NAME || fail +echo $PWD3 | $CRYPTSETUP luksResume -S 4 $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +echo $PWD3 | $CRYPTSETUP luksResume -S 5 $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail -echo -e "$PWD3\n$PWD1" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 0 $LOOPDEV || fail +echo -e "$PWD3\n$PWD1" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 0 $LOOPDEV || fail echo $PWD3 | $CRYPTSETUP luksOpen -S 0 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail echo $PWD1 | $CRYPTSETUP luksOpen -S 5 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail # second, try it with keyfiles $CRYPTSETUP -q luksFormat -q -S 5 $FAST_PBKDF_OPT -d $KEY5 --type luks2 $LOOPDEV || fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail $CRYPTSETUP luksOpen -S 5 -d $KEY5 $LOOPDEV $DEV_NAME || fail check_exists +$CRYPTSETUP luksSuspend $DEV_NAME || fail +$CRYPTSETUP luksResume -S 1 -d $KEY5 $DEV_NAME 2>/dev/null && fail +$CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" || fail +$CRYPTSETUP luksResume -S 5 -d $KEY5 $DEV_NAME || fail $CRYPTSETUP luksClose $DEV_NAME || fail $CRYPTSETUP luksOpen -S 1 -d $KEY5 $LOOPDEV $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail @@ -696,7 +719,7 @@ $CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOPDEV $DEV_NAME 2>/dev/null && fail # otoh it should be allowed to test for proper passphrase prepare "" new echo $PWD1 | $CRYPTSETUP open -S1 --test-passphrase $HEADER_KEYU || fail -echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_KEYU || fail +echo $PWD1 | $CRYPTSETUP open --unbound --test-passphrase $HEADER_KEYU || fail echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME 2>/dev/null && fail [ -b /dev/mapper/$DEV_NAME ] && fail echo $PWD1 | $CRYPTSETUP open $HEADER_KEYU $DEV_NAME 2>/dev/null && fail @@ -705,7 +728,7 @@ echo $PWD0 | $CRYPTSETUP open -S1 --test-passphrase $HEADER_KEYU $DEV_NAME 2>/de $CRYPTSETUP luksKillSlot -q $HEADER_KEYU 0 $CRYPTSETUP luksDump $HEADER_KEYU | grep -q "0: luks2" && fail echo $PWD1 | $CRYPTSETUP open -S1 --test-passphrase $HEADER_KEYU || fail -echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_KEYU || fail +echo $PWD1 | $CRYPTSETUP open --unbound --test-passphrase $HEADER_KEYU || fail echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME 2>/dev/null && fail prepare "[28] Detached LUKS header" wipe @@ -714,7 +737,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --head echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 4096 >/dev/null || fail $CRYPTSETUP luksDump $HEADER_IMG | grep -e "0: crypt" -A1 | grep -qe $((4096*512)) || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 0 --sector-size 512 || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV-missing --header $HEADER_IMG $DEV_NAME 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP -q resize $DEV_NAME --size 100 --header $HEADER_IMG || fail @@ -727,7 +750,7 @@ $CRYPTSETUP luksSuspend $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 +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 5 _fakedev_ --header $HEADER_IMG $KEY5 || fail $CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "5: luks2" || fail $CRYPTSETUP luksKillSlot -q _fakedev_ --header $HEADER_IMG 5 || fail $CRYPTSETUP luksDump _fakedev_ --header $HEADER_IMG | grep -q "5: luks2" && fail @@ -741,10 +764,12 @@ $CRYPTSETUP -q luksDump $HEADER_IMG | grep -q "offset: $((512 * 131072)) \[byte prepare "[29] Repair metadata" wipe xz -dk $HEADER_LUKS2_PV.xz -$CRYPTSETUP isLuks --disable-locks $HEADER_LUKS2_PV && fail -$CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail -$CRYPTSETUP isLuks --disable-locks --type luks2 $HEADER_LUKS2_PV && fail -$CRYPTSETUP isLuks --type luks2 $HEADER_LUKS2_PV && fail +if [ "$HAVE_BLKID" -gt 0 ]; then + $CRYPTSETUP isLuks --disable-locks $HEADER_LUKS2_PV && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + $CRYPTSETUP isLuks --disable-locks --type luks2 $HEADER_LUKS2_PV && fail + $CRYPTSETUP isLuks --type luks2 $HEADER_LUKS2_PV && fail +fi $CRYPTSETUP -q repair $HEADER_LUKS2_PV || fail $CRYPTSETUP isLuks $HEADER_LUKS2_PV || fail $CRYPTSETUP isLuks --type luks2 $HEADER_LUKS2_PV || fail @@ -752,7 +777,7 @@ $CRYPTSETUP isLuks --type luks1 $HEADER_LUKS2_PV && fail prepare "[30] LUKS erase" wipe $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 --key-slot 5 || fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail $CRYPTSETUP luksErase -q $LOOPDEV || fail @@ -761,7 +786,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" && fail prepare "[31] LUKS convert" wipe $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV $KEY5 --key-slot 5 || fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 || fail +$CRYPTSETUP -q luksDump $LOOPDEV --dump-json-metadata >/dev/null 2>&1 && fail $CRYPTSETUP -q convert --type luks1 $LOOPDEV >/dev/null 2>&1 && fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 1: ENABLED" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "Key Slot 5: ENABLED" || fail @@ -770,8 +796,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail $CRYPTSETUP -q convert --type luks1 $LOOPDEV || fail # hash test -$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 $LOOPDEV $KEY5 -S 0 --hash sha1 || fail -$CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 --hash sha256 || fail +$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --sector-size 512 $LOOPDEV $KEY5 -S 0 --hash sha512 || fail +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 1 -d $KEY5 $LOOPDEV $KEY1 --hash sha256 || fail $CRYPTSETUP -q convert --type luks1 $LOOPDEV >/dev/null 2>&1 && fail $CRYPTSETUP -q luksKillSlot $LOOPDEV 1 || fail $CRYPTSETUP -q convert --type luks1 $LOOPDEV || fail @@ -787,6 +813,18 @@ $CRYPTSETUP -q convert --type luks2 $LOOPDEV || fail $CRYPTSETUP isLuks --type luks2 $LOOPDEV || fail $CRYPTSETUP luksOpen $LOOPDEV --test-passphrase --key-slot 0 -d $KEY5 || fail +# keyslot 1 area offset is higher than keyslot 0 area +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 --key-slot 0 $LOOPDEV || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_OPT --key-slot 1 $LOOPDEV || fail +echo -e "$PWD1\n$PWD1" | $CRYPTSETUP -q luksChangeKey $FAST_PBKDF_OPT $LOOPDEV || fail +# convert to LUKS1 and back; LUKS1 does not store length, only offset +$CRYPTSETUP -q convert --type luks1 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q open --test-passphrase $LOOPDEV || fail +echo $PWD2 | $CRYPTSETUP -q open --test-passphrase $LOOPDEV || fail +$CRYPTSETUP -q convert --type luks2 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q open --test-passphrase $LOOPDEV || fail +echo $PWD2 | $CRYPTSETUP -q open --test-passphrase $LOOPDEV || fail + if dm_crypt_keyring_flawed; then prepare "[32a] LUKS2 keyring dm-crypt bug" wipe echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail @@ -794,7 +832,7 @@ if dm_crypt_keyring_flawed; then $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "dm-crypt" || fail $CRYPTSETUP close $DEV_NAME || fail # key must not load in kernel key even when dm-crypt module is missing - if rmmod dm-crypt > /dev/null 2>&1; then + if rmmod dm-crypt >/dev/null 2>&1; then echo $PWD1 | $CRYPTSETUP open $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "dm-crypt" || fail $CRYPTSETUP close $DEV_NAME || fail @@ -806,7 +844,7 @@ if dm_crypt_keyring_support && dm_crypt_keyring_new_kernel; then echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail # check keyring support detection works as expected - rmmod dm-crypt > /dev/null 2>&1 || true + rmmod dm-crypt >/dev/null 2>&1 || true echo $PWD1 | $CRYPTSETUP open $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail $CRYPTSETUP -q status $DEV_NAME | grep "key location:" | grep -q "keyring" || fail $CRYPTSETUP close $DEV_NAME || fail @@ -848,23 +886,56 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then $CRYPTSETUP open --token-only $LOOPDEV --test-passphrase || fail $CRYPTSETUP open --token-only $LOOPDEV $DEV_NAME || fail $CRYPTSETUP status $DEV_NAME > /dev/null || fail + $CRYPTSETUP luksSuspend $DEV_NAME || fail + $CRYPTSETUP luksResume $DEV_NAME <&- || fail + $CRYPTSETUP -q status $DEV_NAME | grep -q "(suspended)" && fail + $CRYPTSETUP luksSuspend $DEV_NAME || fail + $CRYPTSETUP luksResume $DEV_NAME --token-type luks2-keyring <&- || fail $CRYPTSETUP close $DEV_NAME || fail + + # check --token-type sort of works (TODO: extend tests when native systemd tokens are available) + echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 22 || fail + # this excludes keyring tokens from unlocking device + $CRYPTSETUP open --token-only --token-type some_type $LOOPDEV --test-passphrase && fail + $CRYPTSETUP open --token-only --token-type some_type $LOOPDEV $DEV_NAME && fail + $CRYPTSETUP status $DEV_NAME > /dev/null && fail + $CRYPTSETUP token remove --token-id 3 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q -e "3: luks2-keyring" && fail # test we can remove keyslot with token - echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -S4 $FAST_PBKDF_OPT $LOOPDEV || fail - $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN1 --key-slot 4 || fail + echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q -S4 $FAST_PBKDF_OPT $LOOPDEV || fail + $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN1 --key-slot 4 --token-id 0 || fail $CRYPTSETUP -q luksKillSlot $LOOPDEV 4 || fail + $CRYPTSETUP token remove --token-id 0 $LOOPDEV || fail + + # test we can add unassigned token + $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN0 --unbound --token-id 0 || fail + $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $LOOPDEV && fail + $CRYPTSETUP token remove --token-id 0 $LOOPDEV || fail + + # test token unassign works + $CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN0 -S0 --token-id 0 || fail + $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $LOOPDEV || fail + $CRYPTSETUP token unassign --token-id 0 $LOOPDEV 2>/dev/null && fail + $CRYPTSETUP token unassign -S0 $LOOPDEV 2>/dev/null && fail + $CRYPTSETUP token unassign --token-id 0 -S0 $LOOPDEV || fail + $CRYPTSETUP open --token-only --token-id 0 --test-passphrase $LOOPDEV && fail + $CRYPTSETUP token unassign --token-id 0 -S0 $LOOPDEV 2>/dev/null && fail + $CRYPTSETUP token unassign --token-id 0 -S44 $LOOPDEV 2>/dev/null && fail + $CRYPTSETUP token unassign --token-id 44 -S0 $LOOPDEV 2>/dev/null && fail fi echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 10 || fail echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 11 --json-file - || fail echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0 $CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 || fail $CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 2>/dev/null && fail -$CRYPTSETUP token export $LOOPDEV --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail -$CRYPTSETUP token export $LOOPDEV --token-id 11 | diff --from-file - $TOKEN_FILE0 || fail -$CRYPTSETUP token export $LOOPDEV --token-id 12 | diff --from-file - $TOKEN_FILE0 || fail +$CRYPTSETUP token export $LOOPDEV --token-id 10 >$TOKEN_FILE1 || fail +diff $TOKEN_FILE0 $TOKEN_FILE1 || fail +$CRYPTSETUP token export $LOOPDEV --token-id 11 >$TOKEN_FILE1 || fail +diff $TOKEN_FILE0 $TOKEN_FILE1 || fail +$CRYPTSETUP token export $LOOPDEV --token-id 12 >$TOKEN_FILE1 || fail +diff $TOKEN_FILE0 $TOKEN_FILE1 || fail $CRYPTSETUP token export $LOOPDEV --token-id 12 --json-file $TOKEN_FILE1 || fail diff $TOKEN_FILE0 $TOKEN_FILE1 || fail $CRYPTSETUP token export $LOOPDEV --token-id 12 > $TOKEN_FILE1 || fail @@ -872,7 +943,7 @@ diff $TOKEN_FILE0 $TOKEN_FILE1 || fail prepare "[34] LUKS keyslot priority" wipe echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -S 1 || fail -echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $LOOPDEV $FAST_PBKDF_OPT -S 5 || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q $LOOPDEV $FAST_PBKDF_OPT -S 5 || fail $CRYPTSETUP config $LOOPDEV -S 0 --priority prefer && fail $CRYPTSETUP config $LOOPDEV -S 1 --priority bla >/dev/null 2>&1 && fail $CRYPTSETUP config $LOOPDEV -S 1 --priority ignore || fail @@ -928,55 +999,53 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail $CRYPTSETUP -q luksConvertKey $LOOPDEV -S 5 --key-file $KEY5 --pbkdf argon2i -i1 --pbkdf-memory 32 || can_fail_fips $CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || can_fail_fips -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -S 1 --key-file $KEY5 || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV -S 1 --key-file $KEY5 || fail $CRYPTSETUP -q luksKillSlot $LOOPDEV 5 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail echo $PWD1 | $CRYPTSETUP -q luksConvertKey $LOOPDEV -S 1 --pbkdf argon2i -i1 --pbkdf-memory 32 || can_fail_fips $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || can_fail_fips -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 21 --unbound -s 16 $LOOPDEV || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S 21 --unbound -s 72 $LOOPDEV || fail echo $PWD3 | $CRYPTSETUP luksConvertKey --pbkdf-force-iterations 1001 --pbkdf pbkdf2 -S 21 $LOOPDEV || fail prepare "[38] luksAddKey unbound tests" wipe $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 --key-slot 5 || fail # unbound key may have arbitrary size -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 16 $LOOPDEV || fail -echo $PWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 32 -S 2 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 72 $LOOPDEV || fail +echo $PWD2 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --unbound -s 72 -S 2 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" || fail dd if=/dev/urandom of=$KEY_FILE0 bs=64 count=1 > /dev/null 2>&1 || fail -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --unbound -s 512 -S 3 --master-key-file $KEY_FILE0 $LOOPDEV || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --unbound -s 512 -S 3 --volume-key-file $KEY_FILE0 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" || fail # unbound key size is required echo $PWD1 | $CRYPTSETUP -q luksAddKey --unbound $LOOPDEV 2>/dev/null && fail -echo $PWD3 | $CRYPTSETUP -q luksAddKey --unbound --master-key-file /dev/urandom $LOOPDEV 2> /dev/null && fail -# do not allow to replace keyslot by unbound slot +echo $PWD3 | $CRYPTSETUP -q luksAddKey --unbound --volume-key-file /dev/urandom $LOOPDEV 2> /dev/null && fail +# do not allow one to replace keyslot by unbound slot echo $PWD1 | $CRYPTSETUP -q luksAddKey -S5 --unbound -s 32 $LOOPDEV 2>/dev/null && fail echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail -echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV $DEV_NAME 2> /dev/null && fail echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV --test-passphrase || fail echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail -echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail # check we're able to change passphrase for unbound keyslot echo -e "$PWD2\n$PWD3" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail -echo $PWD3 | $CRYPTSETUP open --test-passphrase $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail +echo $PWD3 | $CRYPTSETUP open --test-passphrase -S 2 $LOOPDEV || fail echo $PWD3 | $CRYPTSETUP -q open -S 2 $LOOPDEV $DEV_NAME 2> /dev/null && fail # do not allow adding keyslot by unbound keyslot echo -e "$PWD3\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail # check adding keyslot works when there's unbound keyslot -echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-file $KEY5 -S8 || fail +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT $LOOPDEV --key-file $KEY5 -S8 || fail echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail $CRYPTSETUP close $DEV_NAME || fail $CRYPTSETUP luksKillSlot -q $LOOPDEV 2 $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" && fail -echo $PWD3 | $CRYPTSETUP luksDump --unbound --master-key-file $KEY_FILE1 $LOOPDEV 2> /dev/null && fail +echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 $LOOPDEV 2> /dev/null && fail echo $PWD3 | $CRYPTSETUP luksDump --unbound 2> /dev/null $LOOPDEV 2> /dev/null && fail -echo $PWD3 | $CRYPTSETUP luksDump --unbound --master-key-file $KEY_FILE1 -S3 $LOOPDEV > /dev/null || fail +echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $LOOPDEV > /dev/null || fail diff $KEY_FILE0 $KEY_FILE1 || fail -echo $PWD3 | $CRYPTSETUP luksDump --unbound --master-key-file $KEY_FILE1 -S3 $LOOPDEV 2> /dev/null && fail +echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $LOOPDEV 2> /dev/null && fail diff $KEY_FILE0 $KEY_FILE1 || fail rm $KEY_FILE1 || fail -echo $PWD3 | $CRYPTSETUP luksDump --unbound --master-key-file $KEY_FILE1 -S3 $LOOPDEV | grep -q "Unbound Key:" && fail +echo $PWD3 | $CRYPTSETUP luksDump --unbound --volume-key-file $KEY_FILE1 -S3 $LOOPDEV | grep -q "Unbound Key:" && fail echo $PWD3 | $CRYPTSETUP luksDump --unbound -S3 $LOOPDEV | grep -q "Unbound Key:" || fail $CRYPTSETUP luksKillSlot -q $LOOPDEV 3 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" && fail @@ -988,11 +1057,12 @@ for mda in 16 32 64 128 256 512 1024 2048 4096 ; do echo -n "[$mda KiB]" echo $PWD4 | $CRYPTSETUP open test_image_$mda $DEV_NAME || fail $CRYPTSETUP close $DEV_NAME || fail - echo -e "$PWD4\n$PWD3" | $CRYPTSETUP luksAddKey -S9 $FAST_PBKDF_OPT test_image_$mda || fail + echo -e "$PWD4\n$PWD3" | $CRYPTSETUP luksAddKey -q -S9 $FAST_PBKDF_OPT test_image_$mda || fail echo $PWD4 | $CRYPTSETUP open --test-passphrase test_image_$mda || fail echo $PWD3 | $CRYPTSETUP open -S9 --test-passphrase test_image_$mda || fail echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import test_image_$mda --token-id 10 || fail - $CRYPTSETUP token export test_image_$mda --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail + $CRYPTSETUP token export test_image_$mda --token-id 10 >$TOKEN_FILE1 || fail + diff $TOKEN_FILE1 $TOKEN_FILE0 || fail echo -n "[OK]" done echo @@ -1026,18 +1096,18 @@ KEYSLOT_CIPHER="aes-cbc-plain64" $CRYPTSETUP -q luksFormat --type luks2 $LOOPDEV $KEY1 $FAST_PBKDF_OPT --key-slot 0 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 1 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail +$CRYPTSETUP luksAddKey -q $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 1 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "1: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "1: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail -$CRYPTSETUP luksAddKey $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 2 || fail +$CRYPTSETUP luksAddKey -q $LOOPDEV -d $KEY1 $KEY2 $FAST_PBKDF_OPT --key-slot 2 || fail $CRYPTSETUP luksChangeKey $LOOPDEV $FAST_PBKDF_OPT -d $KEY2 $KEY1 --key-slot 2 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "2: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "2: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail # unbound keyslot -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --key-slot 21 --unbound -s 32 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $LOOPDEV || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --key-slot 21 --unbound -s 72 --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $LOOPDEV || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "21: luks2" | grep "Cipher:" | sed -e 's/[[:space:]]\+Cipher:\ \+//g')" = $KEYSLOT_CIPHER ] || fail [ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "21: luks2" | grep "Cipher key:"| sed -e 's/[[:space:]]\+Cipher\ key:\ \+//g')" = "128 bits" ] || fail -echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --key-slot 22 --unbound -s 32 $LOOPDEV || fail +echo $PWD3 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --key-slot 22 --unbound -s 72 $LOOPDEV || fail echo $PWD3 | $CRYPTSETUP luksConvertKey --key-slot 22 $LOOPDEV --keyslot-cipher $KEYSLOT_CIPHER --keyslot-key-size 128 $LOOPDEV || fail [ "$($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 @@ -1051,5 +1121,84 @@ for cipher in $CIPHERS ; do done echo +prepare "[43] New luksAddKey options." wipe +rm -f $VK_FILE +echo "$PWD1" | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG || fail +echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-volume-key --volume-key-file $VK_FILE >/dev/null || fail + +# pass pass +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -q -S1 $FAST_PBKDF_OPT $IMG || fail +echo $PWD2 | $CRYPTSETUP open -q --test-passphrase -S1 $IMG || fail + +# pass file +echo "$PWD2" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S1 --new-key-slot 2 $IMG $KEY1 || fail +$CRYPTSETUP open --test-passphrase -q -S2 -d $KEY1 $IMG || fail + +# file pass +echo "$PWD3" | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 -d $KEY1 --new-key-slot 3 $IMG || fail +echo $PWD3 | $CRYPTSETUP open -q --test-passphrase -S3 $IMG || fail + +# file file +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 --new-key-slot 4 -d $KEY1 --new-keyfile $KEY2 $IMG || fail +$CRYPTSETUP open --test-passphrase -q -S4 -d $KEY2 $IMG || fail + +# vk pass +echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S5 --volume-key-file $VK_FILE $IMG || fail +echo $PWD4 | $CRYPTSETUP open -q --test-passphrase -S5 $IMG || fail + +# vk file +$CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S6 --volume-key-file $VK_FILE --new-keyfile $KEY5 $IMG || fail +$CRYPTSETUP open --test-passphrase -q -S6 -d $KEY5 $IMG || fail + +if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then + test_and_prepare_keyring + load_key user $TEST_TOKEN0 $PWD1 "$TEST_KEYRING" || fail "Cannot load 32 byte user key type" + load_key user $TEST_TOKEN1 $PWDW "$TEST_KEYRING" || fail "Cannot load 32 byte user key type" + $CRYPTSETUP token add $IMG --key-description $TEST_TOKEN0 --token-id 0 -S0 || fail + $CRYPTSETUP token add $IMG --key-description $TEST_TOKEN1 --token-id 1 --unbound || fail + + # pass token + echo -e "$PWD1" | $CRYPTSETUP luksAddKey -q -S7 --new-token-id 1 $FAST_PBKDF_OPT $IMG || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 7 || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG && fail + + # file token + $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S2 --new-key-slot 7 --new-token-id 1 -d $KEY1 $IMG || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 7 || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG && fail + + # vk token + $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S7 --volume-key-file $VK_FILE --new-token-id 1 $IMG || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 7 || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG && fail + + # token pass + echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S7 --token-id 0 $IMG || fail + echo $PWD4 | $CRYPTSETUP open -q --test-passphrase -S7 $IMG || fail + + # token file + echo $PWD4 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S8 --token-id 0 $IMG $KEY2 || fail + $CRYPTSETUP open -q --test-passphrase -S8 --key-file $KEY2 $IMG || fail + + # token token + $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S9 --token-id 0 --new-token-id 1 $IMG || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 9 || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 1 -q $IMG && fail + + # reuse same token + $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT -S0 --new-key-slot 9 --token-id 0 --new-token-id 0 $IMG || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 9 || fail + + # reuse same token + $CRYPTSETUP luksAddKey -q $FAST_PBKDF_OPT --token-id 0 --new-token-id 0 $IMG || fail + echo $PWD1 | $CRYPTSETUP luksKillSlot $IMG 9 || fail + $CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $IMG || fail +fi + remove_mapping exit 0 diff --git a/tests/compatimage.img.xz b/tests/compatimage.img.xz Binary files differindex 37fe163..cb515f4 100644 --- a/tests/compatimage.img.xz +++ b/tests/compatimage.img.xz diff --git a/tests/conversion_imgs.tar.xz b/tests/conversion_imgs.tar.xz Binary files differindex cdeb961..43e35fe 100644 --- a/tests/conversion_imgs.tar.xz +++ b/tests/conversion_imgs.tar.xz diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c index 004e426..ae8dd68 100644 --- a/tests/crypto-vectors.c +++ b/tests/crypto-vectors.c @@ -1,7 +1,7 @@ /* * cryptsetup crypto backend test vectors * - * Copyright (C) 2018-2021 Milan Broz + * Copyright (C) 2018-2023 Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,8 +22,10 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <unistd.h> +#include <fcntl.h> -#include "crypto_backend.h" +#include "crypto_backend/crypto_backend.h" #ifndef ARRAY_SIZE # define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -40,6 +42,24 @@ static void printhex(const char *s, const char *buf, size_t len) fflush(stdout); } +static bool fips_mode(void) +{ + int fd; + char buf = 0; + + fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY); + + if (fd < 0) + return false; + + if (read(fd, &buf, 1) != 1) + buf = '0'; + + close(fd); + + return (buf == '1'); +} + /* * KDF tests */ @@ -104,6 +124,27 @@ static struct kdf_test_vector kdf_test_vectors[] = { // "\xd0\x1e\xf0\x45\x2d\x75\xb6\x5e" // "\xb5\x25\x20\xe9\x6b\x01\xe6\x59", 32 }, + /* empty password */ + { + "argon2i", NULL, 0, 3, 128, 1, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "\xbb\x1f\xf2\xb9\x9f\xd4\x4a\xd9" + "\xdf\x7f\xb9\x54\x55\x9e\xb8\xeb" + "\xb5\x9d\xab\xce\x2e\x62\x9f\x9b" + "\x89\x09\xfe\xde\x57\xcc\x63\x86", 32 + }, + { + "argon2id", NULL, 0, 3, 128, 1, + "", 0, + "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16, + "\x09\x2f\x38\x35\xac\xb2\x43\x92" + "\x93\xeb\xcd\xe8\x04\x16\x6a\x31" + "\xce\x14\xd4\x55\xdb\xd8\xf7\xe6" + "\xb4\xf5\x9d\x64\x8e\xd0\x3a\xdb", 32 + }, /* RFC 3962 */ { "pbkdf2", "sha1", 64, 1, 0, 0, @@ -912,13 +953,80 @@ static struct cipher_iv_test_vector cipher_iv_test_vectors[] = { }, }}}; +/* Base64 test vectors */ +struct base64_test_vector { + size_t decoded_len; + const char *decoded; + const char *encoded; +}; + +static struct base64_test_vector base64_test_vectors[] = { + { 0, "", "" }, + { 1, "\x00", "AA==" }, + { 1, "f", "Zg==" }, + { 2, "fo", "Zm8=" }, + { 3, "foo", "Zm9v" }, + { 4, "foob", "Zm9vYg==" }, + { 5, "fooba", "Zm9vYmE=" }, + { 6, "foobar", "Zm9vYmFy" }, + { 11, "Hello world", "SGVsbG8gd29ybGQ=" }, + { 22, "\x36\x03\x84\xdc\x4e\x03\x46\xa0\xb5\x2d\x03" + "\x6e\xd0\x56\xed\xa0\x37\x02\xac\xc6\x65\xd1", + "NgOE3E4DRqC1LQNu0FbtoDcCrMZl0Q==" }, + { 3, "***", "Kioq" }, + { 4, "\x01\x02\x03\x04", "AQIDBA==" }, + { 5, "\xAD\xAD\xAD\xAD\xAD", "ra2tra0=" }, + { 5, "\xFF\xFF\xFF\xFF\xFF", "//////8=" }, + { 32, "\x40\xC1\x3F\xBD\x05\x4C\x72\x2A\xA3\xC2\xF2" + "\x11\x73\xC0\x69\xEA\x49\x7D\x35\x29\x6B\xCC" + "\x24\x65\xF6\xF9\xD0\x41\x08\x7B\xD7\xA9", + "QME/vQVMciqjwvIRc8Bp6kl9NSlrzCRl9vnQQQh716k=" }, + { 7, "\x54\x0f\xdc\xf0\x0f\xaf\x4a", "VA/c8A+vSg==" }, + {179, "blah blah blah blah blah blah blah blah blah " + "blah blah blah blah blah blah blah blah blah " + "blah blah blah blah blah blah blah blah blah " + "blah blah blah blah blah blah blah blah blah", + "YmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxh" + "aCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBi" + "bGFoIGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFo" + "IGJsYWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJs" + "YWggYmxhaCBibGFoIGJsYWggYmxhaCBibGFoIGJsYWgg" + "YmxhaCBibGFoIGJsYWg=" }, +}; + +/* UTF8 to UTF16LE test vectors */ +struct utf8_16_test_vector { + size_t len8; + size_t len16; + const char *utf8; + const char *utf16; +}; + +static struct utf8_16_test_vector utf8_16_test_vectors[] = { + { 1, 2, "a", "\x61\x00" }, + { 16, 32, "0123456789abcdef", + "\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00" + "\x38\x00\x39\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00" }, + { 77, 78, + "\xf2\xa4\xa5\x94\x49\xf2\xa1\x98\x98\xd8\x8a\xe1\xb4\x88\xea\xa7" + "\xaa\xde\x95\xe2\x85\xb1\xe7\xb1\x9a\xf2\xb5\xa1\xae\x37\x2d\xd0" + "\xa9\xe1\x9a\x9c\xe8\xb0\xb7\xc8\x95\x0a\xf3\xaa\x92\xba\xf2\x83" + "\xb0\x99\xf0\x9b\xbe\x8f\x4f\xc8\x86\x30\xe7\xab\xa0\xda\xb9\xd8" + "\x89\xd8\xbc\xd7\x8a\xd9\xbc\xc3\x8f\x33\x62\xda\xb7", + "\x52\xda\x54\xdd\x49\x00\x45\xda\x18\xde\x0a\x06\x08\x1d\xea\xa9" + "\x95\x07\x71\x21\x5a\x7c\x96\xda\x6e\xdc\x37\x00\x2d\x00\x29\x04" + "\x9c\x16\x37\x8c\x15\x02\x0a\x00\x69\xdb\xba\xdc\xcf\xd9\x19\xdc" + "\x2f\xd8\x8f\xdf\x4f\x00\x06\x02\x30\x00\xe0\x7a\xb9\x06\x09\x06" + "\x3c\x06\xca\x05\x7c\x06\xcf\x00\x33\x00\x62\x00\xb7\x06" }, +}; + static int pbkdf_test_vectors(void) { char result[256]; unsigned int i; const struct kdf_test_vector *vec; - for (i = 0; i < (sizeof(kdf_test_vectors) / sizeof(*kdf_test_vectors)); i++) { + for (i = 0; i < ARRAY_SIZE(kdf_test_vectors); i++) { crypt_backend_memzero(result, sizeof(result)); vec = &kdf_test_vectors[i]; printf("PBKDF vector %02d %s ", i, vec->type); @@ -1012,17 +1120,37 @@ static int hash_test(void) if (!r) r = crypt_hash_final(h, result, vector->out[j].length); - crypt_hash_destroy(h); - if (r) + if (r) { + crypt_hash_destroy(h); return EXIT_FAILURE; + } if (memcmp(result, vector->out[j].out, vector->out[j].length)) { printf("[FAILED]\n"); printhex(" got", result, vector->out[j].length); printhex("want", vector->out[j].out, vector->out[j].length); + crypt_hash_destroy(h); + return EXIT_FAILURE; + } + + /* + * After crypt_hash_final() the context must be reset, repeat + */ + crypt_backend_memzero(result, sizeof(result)); + r = crypt_hash_write(h, vector->data, vector->data_length); + if (!r) + r = crypt_hash_final(h, result, vector->out[j].length); + + if (r || memcmp(result, vector->out[j].out, vector->out[j].length)) { + printf("[FAILED (RESET CONTEXT)]\n"); + printhex(" got", result, vector->out[j].length); + printhex("want", vector->out[j].out, vector->out[j].length); + crypt_hash_destroy(h); return EXIT_FAILURE; } + + crypt_hash_destroy(h); } printf("\n"); } @@ -1065,17 +1193,36 @@ static int hmac_test(void) if (!r) r = crypt_hmac_final(hmac, result, vector->out[j].length); - crypt_hmac_destroy(hmac); - - if (r) + if (r) { + crypt_hmac_destroy(hmac); return EXIT_FAILURE; + } if (memcmp(result, vector->out[j].out, vector->out[j].length)) { printf("[FAILED]\n"); printhex(" got", result, vector->out[j].length); printhex("want", vector->out[j].out, vector->out[j].length); + crypt_hmac_destroy(hmac); + return EXIT_FAILURE; + } + + /* + * After crypt_hmac_final() the context must be reset, repeat + */ + crypt_backend_memzero(result, sizeof(result)); + r = crypt_hmac_write(hmac, vector->data, vector->data_length); + if (!r) + r = crypt_hmac_final(hmac, result, vector->out[j].length); + + if (r || memcmp(result, vector->out[j].out, vector->out[j].length)) { + printf("[FAILED (RESET CONTEXT)]\n"); + printhex(" got", result, vector->out[j].length); + printhex("want", vector->out[j].out, vector->out[j].length); + crypt_hmac_destroy(hmac); return EXIT_FAILURE; } + + crypt_hmac_destroy(hmac); } printf("\n"); } @@ -1182,7 +1329,9 @@ static int cipher_iv_test(void) if (vector->data_length > sizeof(result)) return EXIT_FAILURE; - snprintf(mode_iv, sizeof(mode_iv)-2, "%s-%s", vector->cipher_mode, vector->iv_name); + if (snprintf(mode_iv, sizeof(mode_iv)-2, "%s-%s", vector->cipher_mode, vector->iv_name) < 0) + return EXIT_FAILURE; + r = crypt_storage_init(&storage, vector->out[j].sector_size, vector->cipher_name, mode_iv, vector->key, vector->key_length, vector->out[j].large_iv); if (r == -ENOENT || r == -ENOTSUP) { @@ -1231,6 +1380,128 @@ static int cipher_iv_test(void) return EXIT_SUCCESS; } +static int check_hash(const char *hash) +{ + struct crypt_hash *h; + + if (crypt_hash_size(hash) < 0) + return EXIT_FAILURE; + + if (crypt_hash_init(&h, hash)) + return EXIT_FAILURE; + + crypt_hash_destroy(h); + return EXIT_SUCCESS; +} + +static int base64_test(void) +{ + unsigned int i; + char *s; + size_t s_len; + + for (i = 0; i < ARRAY_SIZE(base64_test_vectors); i++) { + printf("BASE64 %02d ", i); + s = NULL; + s_len = 0; + if (crypt_base64_encode(&s, &s_len, + base64_test_vectors[i].decoded, + base64_test_vectors[i].decoded_len) < 0) { + printf("[ENCODE FAILED]\n"); + return EXIT_FAILURE; + } else if (strcmp(s, base64_test_vectors[i].encoded)) { + printf("[ENCODE FAILED]\n"); + free(s); + return EXIT_FAILURE; + } + printf("[encode]"); + free(s); + + s = NULL; + s_len = 0; + if (crypt_base64_decode(&s, &s_len, + base64_test_vectors[i].encoded, + strlen(base64_test_vectors[i].encoded)) < 0) { + printf("[DECODE FAILED]\n"); + return EXIT_FAILURE; + } else if (s_len != base64_test_vectors[i].decoded_len || + memcmp(s, base64_test_vectors[i].decoded, s_len)) { + printf("[DECODE FAILED]\n"); + return EXIT_FAILURE; + } + printf("[decode]\n"); + free(s); + } + + return EXIT_SUCCESS; +} + +static int utf8_16_test(void) +{ + unsigned int i; + char s8[128], *s; + char16_t c16[256], s16[256], *su; + + for (i = 0; i < ARRAY_SIZE(utf8_16_test_vectors); i++) { + printf("UTF8/16 %02d ", i); + crypt_backend_memzero(s16, sizeof(s16)); + su = &s16[0]; + if (crypt_utf8_to_utf16(&su, utf8_16_test_vectors[i].utf8, + utf8_16_test_vectors[i].len8) < 0 || + memcmp(utf8_16_test_vectors[i].utf16, s16, + utf8_16_test_vectors[i].len16)) { + printf("[UTF8_TO_UTF16 FAILED]\n"); + return EXIT_FAILURE; + } + printf("[UTF8_TO_UTF16]"); + + crypt_backend_memzero(s8, sizeof(s8)); + s = &s8[0]; + memcpy(c16, utf8_16_test_vectors[i].utf16, utf8_16_test_vectors[i].len16); + if (crypt_utf16_to_utf8(&s, c16, utf8_16_test_vectors[i].len16) < 0 || + utf8_16_test_vectors[i].len8 != strlen(s8) || + memcmp(utf8_16_test_vectors[i].utf8, s8, + utf8_16_test_vectors[i].len8)) { + printf("[UTF16_TO_UTF8 FAILED]\n"); + return EXIT_FAILURE; + } + printf("[UTF16_TO_UTF8]\n"); + } + + return EXIT_SUCCESS; +} + +static int default_alg_test(void) +{ + printf("Defaults: [LUKS1 hash %s] ", DEFAULT_LUKS1_HASH); + if (check_hash(DEFAULT_LUKS1_HASH)) + return EXIT_FAILURE; + + printf("[PLAIN hash %s] ", DEFAULT_PLAIN_HASH); + if (check_hash(DEFAULT_PLAIN_HASH)) + return EXIT_FAILURE; + + printf("[VERITY hash %s] ", DEFAULT_VERITY_HASH); + if (check_hash(DEFAULT_VERITY_HASH)) + return EXIT_FAILURE; + + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + +static int memcmp_test(void) +{ + printf("MEMEQ "); + if (!crypt_backend_memeq("aaaaaaaa", "bbbbbbbb", 8)) + return EXIT_FAILURE; + if (crypt_backend_memeq("aaaaaaaa", "aaaaaaaa", 8)) + return EXIT_FAILURE; + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + static void __attribute__((noreturn)) exit_test(const char *msg, int r) { if (msg) @@ -1248,7 +1519,7 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[] exit(77); } - if (crypt_backend_init()) + if (crypt_backend_init(fips_mode())) exit_test("Crypto backend init error.", EXIT_FAILURE); printf("Test vectors using %s crypto backend.\n", crypt_backend_version()); @@ -1268,5 +1539,21 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[] if (cipher_iv_test()) exit_test("IV test failed.", EXIT_FAILURE); + if (base64_test()) + exit_test("BASE64 test failed.", EXIT_FAILURE); + + if (memcmp_test()) + exit_test("Memcmp test failed.", EXIT_FAILURE); + + if (utf8_16_test()) + exit_test("UTF8/16 test failed.", EXIT_FAILURE); + + if (default_alg_test()) { + if (fips_mode()) + printf("\nDefault compiled-in algorithms test ignored (FIPS mode on).\n"); + else + exit_test("\nDefault compiled-in algorithms test failed.", EXIT_FAILURE); + } + exit_test(NULL, EXIT_SUCCESS); } diff --git a/tests/cryptsetup-valg-supps b/tests/cryptsetup-valg-supps index 493e125..fc9913a 100644 --- a/tests/cryptsetup-valg-supps +++ b/tests/cryptsetup-valg-supps @@ -1,4 +1,4 @@ -# Suppresion file for valgrind +# Suppression file for valgrind # known problem in libgcrypt { diff --git a/tests/device-test b/tests/device-test index 617f16a..c8b53bb 100755 --- a/tests/device-test +++ b/tests/device-test @@ -10,14 +10,17 @@ PWD2="mymJeD8ivEhE" FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" SKIP_COUNT=0 +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + cleanup() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME udevadm settle >/dev/null 2>&1 if [ -d "$MNT_DIR" ] ; then - umount -f $MNT_DIR 2>/dev/null - rmdir $MNT_DIR 2>/dev/null + umount -f $MNT_DIR 2>/dev/null + rmdir $MNT_DIR 2>/dev/null fi - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 } fail() @@ -36,8 +39,23 @@ skip() exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + add_device() { - modprobe scsi_debug $@ delay=0 + rmmod scsi_debug >/dev/null 2>&1 + [ -d /sys/module/scsi_debug ] && skip "Cannot use scsi_debug module (in use or compiled-in)." + + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 [ $? -ne 0 ] && skip "This kernel seems to not support proper scsi_debug module." sleep 1 @@ -46,9 +64,14 @@ add_device() { [ -b "/dev/$SCSI_DEV" ] || fail "Cannot find $SCSI_DEV." } +add_image() +{ + dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 +} + function dm_crypt_features() { - modprobe dm-crypt || fail "dm-crypt failed to load" + modprobe dm-crypt >/dev/null 2>&1 || 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." @@ -94,13 +117,13 @@ function dm_crypt_keyring_support() format() # format { - dd if=/dev/zero of=$DEV bs=1M count=32 >/dev/null 2>&1 + add_image echo $PWD1 | $CRYPTSETUP luksFormat --type $1 $DEV -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 [ $? -ne 0 ] && fail "Format failed." # test some operation, just in case - echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --key-slot 1 + echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --new-key-slot 1 [ $? -ne 0 ] && fail "Keyslot add failed." $CRYPTSETUP -q luksKillSlot $DEV 1 @@ -115,6 +138,14 @@ check_sector_size() # $1 expected sector size fi } +check_io() +{ + dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M count=32 iflag=direct 2>/dev/null || fail + dd if=/dev/zero of=/dev/mapper/$DEV_NAME bs=1M count=32 oflag=direct 2>/dev/null || fail +} + +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run if [ $(id -u) != 0 ]; then skip "You must be root to run this test, test skipped." fi @@ -126,8 +157,8 @@ dm_crypt_features echo "[1] Using tmpfs for image" DEV="$MNT_DIR/test.img" mount -t tmpfs none $MNT_DIR || skip "Mounting tmpfs not available." -format luks1 +add_image echo "[2] Kernel dmcrypt performance options" if [ -z "$DM_PERF_CPU" ]; then echo "TEST SKIPPED: dmcrypt options not available" @@ -137,11 +168,13 @@ else 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 + check_io $CRYPTSETUP close $DEV_NAME || fail echo -n "allow_discards " echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail $CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail $CRYPTSETUP status $DEV_NAME | grep -q discards || fail + check_io $CRYPTSETUP close $DEV_NAME || fail echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME || fail echo -e "$PWD1" | $CRYPTSETUP refresh --hash sha256 -q $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail @@ -161,10 +194,12 @@ else 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 + check_io fi $CRYPTSETUP close $DEV_NAME || fail echo + format luks1 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 @@ -310,8 +345,8 @@ 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 + echo -n "$F" # 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 @@ -319,7 +354,7 @@ for F in LUKS1 LUKS2 BITLK TCRYPT; do udevadm settle >/dev/null 2>&1 $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail dmsetup remove $DEV_NAME --retry || fail - rmmod scsi_debug + rmmod scsi_debug >/dev/null 2>&1 echo -n "[OK] " done echo diff --git a/tests/differ.c b/tests/differ.c index ec811a4..95da8e5 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-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/tests/discards-test b/tests/discards-test index 8a838e6..870f74d 100755 --- a/tests/discards-test +++ b/tests/discards-test @@ -6,10 +6,13 @@ DEV_NAME="discard-t3st" DEV="" PWD1="93R4P4pIqAH8" +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + cleanup() { [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME udevadm settle >/dev/null 2>&1 - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 sleep 2 } @@ -21,8 +24,31 @@ fail() exit 100 } +skip() +{ + [ -n "$1" ] && echo "$1" + exit 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + add_device() { - modprobe scsi_debug $@ delay=0 + rmmod scsi_debug >/dev/null 2>&1 + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "This kernel seems to not support proper scsi_debug module, test skipped." exit 77 @@ -49,12 +75,13 @@ function check_version() return 1 } +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 fi -modprobe --dry-run scsi_debug || exit 77 modprobe dm-crypt >/dev/null 2>&1 if ! check_version ; then echo "Probably old kernel, test skipped." @@ -76,7 +103,7 @@ dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail $CRYPTSETUP luksClose $DEV_NAME || fail echo "[2] Allowing discards for plain device" -echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --hash sha1 --allow-discards || fail +echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --hash sha256 --allow-discards || fail $CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail $CRYPTSETUP resize $DEV_NAME --size 100 || fail $CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail diff --git a/tests/fake_systemd_tpm_path.c b/tests/fake_systemd_tpm_path.c new file mode 100644 index 0000000..6d82989 --- /dev/null +++ b/tests/fake_systemd_tpm_path.c @@ -0,0 +1,17 @@ +#include <string.h> +#include <stdlib.h> + +/* systemd tpm2-util.h */ +int tpm2_find_device_auto(int log_level, char **ret); + +extern int tpm2_find_device_auto(int log_level __attribute__((unused)), char **ret) +{ + const char *path = getenv("TPM_PATH"); + + if (!path) + *ret = NULL; + else + *ret = strdup(path); + + return 0; +} diff --git a/tests/fake_token_path.c b/tests/fake_token_path.c new file mode 100644 index 0000000..7b2bad3 --- /dev/null +++ b/tests/fake_token_path.c @@ -0,0 +1,6 @@ +#include <libcryptsetup.h> + +const char *crypt_token_external_path(void) +{ + return BUILD_DIR; +} diff --git a/tests/fuzz/FuzzerInterface.h b/tests/fuzz/FuzzerInterface.h new file mode 100644 index 0000000..b238253 --- /dev/null +++ b/tests/fuzz/FuzzerInterface.h @@ -0,0 +1,81 @@ +// Based on https://github.com/llvm-mirror/compiler-rt/blob/master/lib/fuzzer/FuzzerInterface.h +// +//===- FuzzerInterface.h - Interface header for the Fuzzer ------*- C++ -* ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Define the interface between libFuzzer and the library being tested. +//===----------------------------------------------------------------------===// + +// NOTE: the libFuzzer interface is thin and in the majority of cases +// you should not include this file into your target. In 95% of cases +// all you need is to define the following function in your file: +// extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); + +// WARNING: keep the interface in C. + +#ifndef LLVM_FUZZER_INTERFACE_H +#define LLVM_FUZZER_INTERFACE_H + +#include <stddef.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// Define FUZZER_INTERFACE_VISIBILITY to set default visibility in a way that +// doesn't break MSVC. +#if defined(_WIN32) +#define FUZZER_INTERFACE_VISIBILITY __declspec(dllexport) +#else +#define FUZZER_INTERFACE_VISIBILITY __attribute__((visibility("default"))) +#endif + +// Mandatory user-provided target function. +// Executes the code under test with [Data, Data+Size) as the input. +// libFuzzer will invoke this function *many* times with different inputs. +// Must return 0. +FUZZER_INTERFACE_VISIBILITY int +LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); + +// Optional user-provided initialization function. +// If provided, this function will be called by libFuzzer once at startup. +// It may read and modify argc/argv. +// Must return 0. +FUZZER_INTERFACE_VISIBILITY int LLVMFuzzerInitialize(int *argc, char ***argv); + +// Optional user-provided custom mutator. +// Mutates raw data in [Data, Data+Size) inplace. +// Returns the new size, which is not greater than MaxSize. +// Given the same Seed produces the same mutation. +FUZZER_INTERFACE_VISIBILITY size_t +LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize, + unsigned int Seed); + +// Optional user-provided custom cross-over function. +// Combines pieces of Data1 & Data2 together into Out. +// Returns the new size, which is not greater than MaxOutSize. +// Should produce the same mutation given the same Seed. +FUZZER_INTERFACE_VISIBILITY size_t +LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, + const uint8_t *Data2, size_t Size2, uint8_t *Out, + size_t MaxOutSize, unsigned int Seed); + +// Experimental, may go away in future. +// libFuzzer-provided function to be used inside LLVMFuzzerCustomMutator. +// Mutates raw data in [Data, Data+Size) inplace. +// Returns the new size, which is not greater than MaxSize. +FUZZER_INTERFACE_VISIBILITY size_t +LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); + +#undef FUZZER_INTERFACE_VISIBILITY + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // LLVM_FUZZER_INTERFACE_H diff --git a/tests/fuzz/LUKS2.proto b/tests/fuzz/LUKS2.proto new file mode 100644 index 0000000..3a0f287 --- /dev/null +++ b/tests/fuzz/LUKS2.proto @@ -0,0 +1,379 @@ +/* + * cryptsetup LUKS2 custom mutator + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +syntax = "proto2"; + +package LUKS2_proto; + +// --------------------------------------------------------------------------- +// ----------------------------- GENERIC OBJECTS ----------------------------- +// --------------------------------------------------------------------------- + +message object_id { + oneof id { + // int_id will be mapped to range -16 to 16 (mod 33) + // this way iy should be easier to generate valid + // object cross-references + uint32 int_id = 1; + string string_id = 2; + } +} + +message string_uint64 { + required bool negative = 1; + oneof number { + uint32 uint_num = 2; + string string_num = 3; + } +} + +enum hash_algorithm { + HASH_ALG_SHA1 = 1; + HASH_ALG_SHA256 = 2; +} + + +// --------------------------------------------------------------------------- +// ----------------------------- BINARY HEADER ------------------------------- +// --------------------------------------------------------------------------- + +enum luks2_magic { + INVALID = 0; + FIRST = 1; + SECOND = 2; +} + +enum luks_version { + ONE = 1; + TWO = 2; + THREE = 3; +} + +// we limit the size to 64KiB to make the fuzzing faster +// because the checksum needs to be calculated for the whole image +enum hdr_size { + size_16_KB = 16384; + size_32_KB = 32768; + size_64_KB = 65536; +// size_128_KB = 131072; +// size_256_KB = 262144; +// size_512_KB = 524288; +// size_1_MB = 1048576; +// size_2_MB = 2097152; +// size_4_MB = 4194304; +} + +enum seqid_description { + PRIMARY_GREATER = 0; + SECONDARY_GREATER = 1; + EQUAL = 2; +} + +// message luks2_hdr_disk { +// char magic[LUKS2_MAGIC_L]; +// //uint16_t version; /* Version 2 */ +// uint64_t hdr_size; /* in bytes, including JSON area */ +// uint64_t seqid; /* increased on every update */ +// char label[LUKS2_LABEL_L]; +// char checksum_alg[LUKS2_CHECKSUM_ALG_L]; +// uint8_t salt[LUKS2_SALT_L]; /* unique for every header/offset */ +// char uuid[LUKS2_UUID_L]; +// char subsystem[LUKS2_LABEL_L]; /* owner subsystem label */ +// uint64_t hdr_offset; /* offset from device start in bytes */ +// char _padding[184]; +// uint8_t csum[LUKS2_CHECKSUM_L]; +// } +message LUKS2_header { + required luks_version version = 1; + required luks2_magic magic = 2; + required hdr_size hdr_size = 3; + required bool use_correct_checksum = 4; + + optional uint64 selected_offset = 5; +} + +message LUKS2_both_headers { + required LUKS2_header primary_header = 1; + required LUKS2_header secondary_header = 2; + + required seqid_description seqid = 3; + required json_area_description json_area = 4; +} + +message json_area_description { + optional config_description config = 1; + repeated keyslot_description keyslots = 2; + repeated digest_description digests = 3; + repeated segment_description segments = 4; + repeated token_description tokens = 5; +} + +// --------------------------------------------------------------------------- +// ----------------------------- KEYSLOT OBJECT ------------------------------ +// --------------------------------------------------------------------------- + +enum keyslot_type { + KEYSLOT_TYPE_LUKS2 = 1; + KEYSLOT_TYPE_REENCRYPT = 2; + KEYSLOT_TYPE_PLACEHOLDER = 3; +} + +enum reencrypt_keyslot_mode { + MODE_REENCRYPT = 1; + MODE_ENCRYPT = 2; + MODE_DECRYPT = 3; +} + +enum reencrypt_keyslot_direction { + DIRECTION_FORWARD = 1; + DIRECTION_BACKWARD = 2; +} + +// The area object contains these mandatory fields: +// - type [string] the area type. +// - offset [string-uint64] the offset from the device start to the beginning of the binary area (in bytes). +// - size [string-uint64] the area size (in bytes). +// +// Area type raw contains these additional fields: +// - encryption [string] the area encryption algorithm, in dm-crypt notation (for example aes-xts-plain64). +// - key_size [integer] the area encryption key size. +// +// Area type none and journal (used only for reencryption optional extension) contain only mandatory fields. +// +// Area type checksum (used only for reencryption optional extension) contains these additional fields: +// - hash [string] The hash algorithm for the checksum resilience mode. +// - sector_size [integer] The data unit size for digest checksum calculated with the hash algorithm. +// +// Area type datashift (used only for reencryption optional extension) contains this additional field: +// - shift_size [string-uint64] The data shift (in bytes) performed during reencryption (shift direction is according to direction field). + +enum keyslot_area_type { + KEYSLOT_AREA_TYPE_RAW = 1; + KEYSLOT_AREA_TYPE_NONE = 2; + KEYSLOT_AREA_TYPE_JOURNAL = 3; + KEYSLOT_AREA_TYPE_CHECKSUM = 4; + KEYSLOT_AREA_TYPE_DATASHIFT = 5; +} + +message keyslot_area_description { + // mandatory fields + optional keyslot_area_type type = 1; + optional string_uint64 offset = 2; + optional string_uint64 size = 3; + + // raw type fields + optional string encryption = 4; + optional int32 key_size = 5; + + // checksum type field + optional hash_algorithm hash = 6; + optional int32 sector_size = 7; + + // datashift type fields + optional string_uint64 shift_size = 8; +} + +// The object describes PBKDF attributes used for the keyslot. +// The kdf object mandatory fields are: +// - type [string] the PBKDF type. +// - salt [base64] the salt for PBKDF (binary data). +// +// The pbkdf2 type (compatible with LUKS1) contains these additional fields: +// - hash [string] the hash algorithm for the PBKDF2 (SHA-256). +// - iterations [integer] the PBKDF2 iterations count. +// +// The argon2i and argon2id type contains these additional fields: +// - time [integer] the time cost (in fact the iterations count for Argon2). +// - memory [integer] the memory cost, in kilobytes. If not available, the keyslot cannot be unlocked. +// - cpus [integer] the required number of threads (CPU cores number cost). If not available, unlocking will be slower. + +enum keyslot_kdf_type { + KEYSLOT_KDF_TYPE_PBKDF2 = 1; + KEYSLOT_KDF_TYPE_ARGON2I = 2; + KEYSLOT_KDF_TYPE_ARGON2ID = 3; +} + +message keyslot_kdf_description { + optional keyslot_kdf_type type = 1; + optional string salt = 2; + + // pbkdf2 type + optional hash_algorithm hash = 3; + optional int32 iterations = 4; + + // argon2i and argon2id types + optional int32 time = 5; + optional int32 memory = 6; + optional int32 cpus = 7; +} + +enum keyslot_af_type { + KEYSLOT_AF_TYPE_LUKS1 = 1; +} + +// The af (anti-forensic splitter) object contains this madatory field: +// - type [string] the anti-forensic function type. +// AF type luks1 (compatible with LUKS1 [1]) contains these additional fields: +// - stripes [integer] the number of stripes, for historical reasons only the 4000 value is supported. +// - hash [string] the hash algorithm used. + +message keyslot_af_description { + optional keyslot_af_type type = 1; + optional int32 stripes = 2; + optional hash_algorithm hash = 3; +} + +// - type [string] the keyslot type. +// - key_size [integer] the key size (in bytes) stored in keyslot. +// - priority [integer,optional] the keyslot priority. Here 0 means ignore (the slot should be used only if explicitly stated), 1 means normal priority and 2 means high priority (tried before normal priority). + +// REENCRYPT +// The key size field must be set to 1. The area type must be none, checksum, +// journal or datashift. +// The reencrypt object must contain these additional fields: +// - mode [string] the reencryption mode. reencrypt, encrypt and decrypt +// - direction [string] the reencryption direction. forward backward + +// - area [object] the allocated area in the binary keyslots area. +// LUKS2 object must contain these additional fields: +// - kdf [object] the PBKDF type and parameters used. +// - af [object] the anti-forensic splitter [1] (only the luks1 type is currently +// used). + +message keyslot_description { + // type + required object_id oid = 1; + + optional keyslot_type type = 2; + optional int32 key_size = 3; + optional int32 priority = 4; + + // reencrypt extension + optional reencrypt_keyslot_mode mode = 5; + optional reencrypt_keyslot_direction direction = 6; + + // objects + optional keyslot_area_description area = 7; + optional keyslot_kdf_description kdf = 8; + optional keyslot_af_description af = 9; +} + +// --------------------------------------------------------------------------- +// ------------------------------ DIGEST OBJECT ------------------------------ +// --------------------------------------------------------------------------- + +message digest_description { + required object_id oid = 1; + + optional keyslot_kdf_type type = 2; + repeated object_id keyslots = 3; + repeated object_id segments = 4; + optional string salt = 5; + optional string digest = 6; + + // pbkdf2 digest fields + optional hash_algorithm hash = 7; + optional int32 iterations = 8; +} + +// --------------------------------------------------------------------------- +// ----------------------------- SEGMENT OBJECT ------------------------------ +// --------------------------------------------------------------------------- + +enum segment_type { + SEGMENT_TYPE_LINEAR = 1; + SEGMENT_TYPE_CRYPT = 2; +} + +enum segment_flag { + IN_REENCRYPTION = 1; + BACKUP_FINAL = 2; + BACKUP_PREVIOUS = 3; + BACKUP_MOVED_SEGMENT = 4; +} + +message segment_integrity_description { + optional string type = 1; + optional string journal_encryption = 2; + optional string journal_integrity = 3; +} + +message segment_description { + required object_id oid = 1; + optional segment_type type = 2; + optional string_uint64 offset = 3; + optional string_uint64 size = 4; + repeated segment_flag flags = 5; + + // segment type crypt + optional string_uint64 iv_tweak = 6; + optional string encryption = 7; + optional int32 sector_size = 8; + optional segment_integrity_description integrity = 9; +} + +// --------------------------------------------------------------------------- +// ------------------------------ TOKEN OBJECT ------------------------------- +// --------------------------------------------------------------------------- + +message token_description { + required object_id oid = 1; + + optional string type = 2; + repeated object_id keyslots = 3; + optional string key_description = 4; +} + +// --------------------------------------------------------------------------- +// ------------------------------ CONFIG OBJECT ------------------------------ +// --------------------------------------------------------------------------- + +// - allow-discards allows TRIM (discards) on the active device. +// - same-cpu-crypt compatibility performance flag for dm-crypt [3] to per- form encryption using the same CPU that originated the request. +// - submit-from-crypt-cpus compatibility performance flag for dm-crypt [3] to disable offloading write requests to a separate thread after encryption. +// - no-journal disable data journalling for dm-integrity [10]. +// - no-read-workqueue compatibility performance flag for dm-crypt [3] to bypass dm-crypt read workqueue and process read requests synchronously. +// - no-write-workqueue compatibility performance flag for dm-crypt [3] to bypass dm-crypt write workqueue and process write requests synchronously. +enum config_flag { + CONFIG_FLAG_ALLOW_DISCARDS = 1; + CONFIG_FLAG_SAME_CPU_CRYPT = 2; + CONFIG_FLAG_SUBMIT_FROM_CRYPT_CPUS = 3; + CONFIG_FLAG_NO_JOURNAL = 4; + CONFIG_FLAG_NO_READ_WORKQUEUE = 5; + CONFIG_FLAG_NO_WRITE_WORKQUEUE = 6; +} + +enum config_requirement { + CONFIG_REQUIREMENT_OFFLINE_REENCRYPT = 1; + CONFIG_REQUIREMENT_ONLINE_REENCRYPT_V2 = 2; +} + +// - json_size [string-uint64] the JSON area size (in bytes). Must match the binary header. +// - keyslots_size [string-uint64] the binary keyslot area size (in bytes). Must be aligned to 4096 bytes. +// - flags [array, optional] the array of string objects with persistent flags for the device. +// - requirements [array, optional] the array of string objects with additional required features for the LUKS device. + +message config_description { + required bool use_primary_hdr_size = 2; + + repeated config_flag config_flags = 3; + repeated config_requirement requirements = 4; +} diff --git a/tests/fuzz/LUKS2_plain_JSON.proto b/tests/fuzz/LUKS2_plain_JSON.proto new file mode 100644 index 0000000..59096b7 --- /dev/null +++ b/tests/fuzz/LUKS2_plain_JSON.proto @@ -0,0 +1,190 @@ +/* + * cryptsetup LUKS2 custom mutator + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +syntax = "proto2"; + +package json_proto; + +// --------------------------------------------------------------------------- +// ----------------------------- GENERIC OBJECTS ----------------------------- +// --------------------------------------------------------------------------- + +message object_id { + oneof id { + // int_id will be mapped to range -16 to 16 (mod 33) + // this way iy should be easier to generate valid + // object cross-references + uint32 int_id = 1; + string string_id = 2; + } +} + +message string_uint64 { + required bool negative = 1; + oneof number { + uint32 uint_num = 2; + string string_num = 3; + } +} + +enum hash_algorithm { + HASH_ALG_SHA1 = 1; + HASH_ALG_SHA256 = 2; +} + + +// --------------------------------------------------------------------------- +// ----------------------------- BINARY HEADER ------------------------------- +// --------------------------------------------------------------------------- + +enum luks2_magic { + INVALID = 0; + FIRST = 1; + SECOND = 2; +} + +enum luks_version { + ONE = 1; + TWO = 2; + THREE = 3; +} + +// we limit the size to 64KiB to make the fuzzing faster +// because the checksum needs to be calculated for the whole image +enum hdr_size { + size_16_KB = 16384; + size_32_KB = 32768; + size_64_KB = 65536; +// size_128_KB = 131072; +// size_256_KB = 262144; +// size_512_KB = 524288; +// size_1_MB = 1048576; +// size_2_MB = 2097152; +// size_4_MB = 4194304; +} + +enum seqid_description { + PRIMARY_GREATER = 0; + SECONDARY_GREATER = 1; + EQUAL = 2; +} + +// message luks2_hdr_disk { +// char magic[LUKS2_MAGIC_L]; +// //uint16_t version; /* Version 2 */ +// uint64_t hdr_size; /* in bytes, including JSON area */ +// uint64_t seqid; /* increased on every update */ +// char label[LUKS2_LABEL_L]; +// char checksum_alg[LUKS2_CHECKSUM_ALG_L]; +// uint8_t salt[LUKS2_SALT_L]; /* unique for every header/offset */ +// char uuid[LUKS2_UUID_L]; +// char subsystem[LUKS2_LABEL_L]; /* owner subsystem label */ +// uint64_t hdr_offset; /* offset from device start in bytes */ +// char _padding[184]; +// uint8_t csum[LUKS2_CHECKSUM_L]; +// } +message LUKS2_header { + required luks_version version = 1; + required luks2_magic magic = 2; + required hdr_size hdr_size = 3; + required bool use_correct_checksum = 4; + + optional uint64 selected_offset = 5; +} + +message LUKS2_both_headers { + required LUKS2_header primary_header = 1; + required LUKS2_header secondary_header = 2; + + required seqid_description seqid = 3; + required JsonObject json_area = 4; +} + +message JsonObject { + required string name = 1; + required JsonValue value = 2; +} + +message JsonValue { + oneof value { + // Json value types: + + // null: null, will be used when 'oneof' contains nothing + + // object: another json object of any type + JsonObject object_value = 1; + + // array: an array of values + ArrayValue array_value = 2; + + // number: can be an integer, a float, an exponent + NumberValue number_value = 3; + + // string: unicode string + StringValue string_value = 4; + + // boolean: true or talse + BooleanValue boolean_value = 5; + } +} + +message ArrayValue { + repeated JsonValue value = 1; +} + +message NumberInteger { + required int64 value = 1; +} + +message NumberFloat { + required double value = 1; +} + +message NumberExponent { + required int32 base = 1; + required int32 exponent = 2; + required bool use_uppercase = 3; +} + +message NumberExponentFrac { + required float base = 1; + required int32 exponent = 2; + required bool use_uppercase = 3; +} + +message NumberValue { + required NumberInteger integer_value = 1; + + // integer_value is used when oneof field below has nothing. + oneof value { + NumberFloat float_value = 2; + NumberExponent exponent_value = 3; + NumberExponentFrac exponent_frac_value = 4; + } +} + +message StringValue { + required string value = 1; +} + +message BooleanValue { + required bool value = 1; +} diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am new file mode 100644 index 0000000..c7a6cdf --- /dev/null +++ b/tests/fuzz/Makefile.am @@ -0,0 +1,122 @@ +EXTRA_DIST = README.md oss-fuzz-build.sh +dist_noinst_DATA = \ + LUKS2.proto \ + LUKS2_plain_JSON.proto \ + crypt2_load_fuzz.dict \ + crypt2_load_ondisk_fuzz.dict \ + crypt2_load_proto_plain_json_fuzz.dict \ + unpoison-mutated-buffers-from-libfuzzer.patch +CLEANFILES = \ + LUKS2.pb.h \ + LUKS2.pb.cc \ + LUKS2_plain_JSON.pb.h \ + LUKS2_plain_JSON.pb.cc + +distclean-local: + -rm -rf out build + +LIB_FUZZING_ENGINE := $(if $(LIB_FUZZING_ENGINE),$(LIB_FUZZING_ENGINE),"-fsanitize=fuzzer") +SANITIZER := $(if $(SANITIZER),,"-fsanitize=address") + +DEPS_PATH := $(top_srcdir)/tests/fuzz/build/static_lib_deps + +crypt2_load_fuzz_SOURCES = FuzzerInterface.h crypt2_load_fuzz.cc +crypt2_load_fuzz_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib +crypt2_load_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) +crypt2_load_fuzz_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz + +crypt2_load_ondisk_fuzz_SOURCES = FuzzerInterface.h crypt2_load_ondisk_fuzz.cc +crypt2_load_ondisk_fuzz_LDADD = ../../libcryptsetup.la -L$(DEPS_PATH)/lib +crypt2_load_ondisk_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) +crypt2_load_ondisk_fuzz_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz + +test-environment-m: + @ if test ! -d $(DEPS_PATH); then \ + echo "You need to build static libraries first; use oss-fuzz-build.sh script."; \ + exit 1; \ + fi +test-environment: | test-environment-m $(DEPS_PATH) + +LUKS2.pb.h: LUKS2.proto + $(DEPS_PATH)/bin/protoc LUKS2.proto --cpp_out=. +LUKS2.pb.cc: LUKS2.pb.h + +LUKS2_plain_JSON.pb.h: LUKS2_plain_JSON.proto + $(DEPS_PATH)/bin/protoc LUKS2_plain_JSON.proto --cpp_out=. +LUKS2_plain_JSON.pb.cc: LUKS2_plain_JSON.pb.h + +crypt2_load_proto_fuzz-crypt2_load_proto_fuzz.$(OBJEXT): LUKS2.pb.cc +crypt2_load_proto_plain_json_fuzz-crypt2_load_proto_plain_json_fuzz.$(OBJEXT): LUKS2_plain_JSON.pb.cc + +nodist_crypt2_load_proto_fuzz_SOURCES = LUKS2.pb.h LUKS2.pb.cc +crypt2_load_proto_fuzz_SOURCES = FuzzerInterface.h \ + crypt2_load_proto_fuzz.cc \ + proto_to_luks2_converter.h \ + proto_to_luks2_converter.cc +crypt2_load_proto_fuzz_LDADD = \ + ../../libcryptsetup.la \ + ../../libcrypto_backend.la \ + -L$(DEPS_PATH)/lib -lprotobuf-mutator-libfuzzer -lprotobuf-mutator -lprotobuf +crypt2_load_proto_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) +crypt2_load_proto_fuzz_CXXFLAGS = $(AM_CXXFLAGS) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/fuzz \ + -I$(DEPS_PATH)/include \ + -I$(DEPS_PATH)/include/libprotobuf-mutator -I$(DEPS_PATH)/include/libprotobuf-mutator/src + +nodist_crypt2_load_proto_plain_json_fuzz_SOURCES = LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc +crypt2_load_proto_plain_json_fuzz_SOURCES = FuzzerInterface.h \ + crypt2_load_proto_plain_json_fuzz.cc \ + json_proto_converter.h \ + json_proto_converter.cc \ + plain_json_proto_to_luks2_converter.h \ + plain_json_proto_to_luks2_converter.cc +crypt2_load_proto_plain_json_fuzz_LDADD = \ + ../../libcryptsetup.la \ + ../../libcrypto_backend.la \ + -L$(DEPS_PATH)/lib -lprotobuf-mutator-libfuzzer -lprotobuf-mutator -lprotobuf +crypt2_load_proto_plain_json_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) +crypt2_load_proto_plain_json_fuzz_CXXFLAGS = $(AM_CXXFLAGS) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/fuzz \ + -I$(DEPS_PATH)/include \ + -I$(DEPS_PATH)/include/libprotobuf-mutator -I$(DEPS_PATH)/include/libprotobuf-mutator/src + +nodist_proto_to_luks2_SOURCES = LUKS2.pb.h LUKS2.pb.cc +proto_to_luks2_SOURCES = \ + proto_to_luks2.cc \ + proto_to_luks2_converter.h \ + proto_to_luks2_converter.cc +proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib -lprotobuf +proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link $(SANITIZER) +proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/fuzz \ + -I$(DEPS_PATH)/include + +nodist_plain_json_proto_to_luks2_SOURCES = LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc +plain_json_proto_to_luks2_SOURCES = \ + plain_json_proto_to_luks2.cc \ + plain_json_proto_to_luks2_converter.h \ + plain_json_proto_to_luks2_converter.cc \ + json_proto_converter.h \ + json_proto_converter.cc +plain_json_proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib -lprotobuf +plain_json_proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link $(SANITIZER) +plain_json_proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/fuzz \ + -I$(DEPS_PATH)/include + +if ENABLE_FUZZ_TARGETS +noinst_PROGRAMS = \ + crypt2_load_fuzz \ + crypt2_load_ondisk_fuzz \ + crypt2_load_proto_fuzz \ + crypt2_load_proto_plain_json_fuzz \ + proto_to_luks2 \ + plain_json_proto_to_luks2 + +fuzz-targets: test-environment $(noinst_PROGRAMS) +.PHONY: fuzz-targets +endif diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md new file mode 100644 index 0000000..fdcfa27 --- /dev/null +++ b/tests/fuzz/README.md @@ -0,0 +1,66 @@ +# Fuzzing target for cryptsetup project + +This directory contains experimental targets for fuzzing testing. +It can be run in the OSS-Fuzz project but also compiled separately. + +# Requirements + +Fuzzers use address sanitizer. To properly detect problems, all +important libraries must be compiled statically with sanitizer enabled. + +Compilation requires *clang* and *clang++* compilers (gcc is not +supported yet). + +# Standalone build + +The script `oss-fuzz-build.sh` can be used to prepare the tree +with pre-compiled library dependencies. +We use upstream git for projects, which can clash with locally +installed versions. The best is to use only basic system installation +without development packages (script will use custom include, libs, +and pkg-config paths). + +# Build Docker image and fuzzers + +You can also run OSS-Fuzz in a Docker image, use these commands +to prepare fuzzers: +``` +sudo python3 infra/helper.py build_image cryptsetup +sudo python3 infra/helper.py build_fuzzers cryptsetup +``` +On SELinux systems also add (https://github.com/google/oss-fuzz/issues/30): +``` +sudo chcon -Rt svirt_sandbox_file_t build/ +``` + +# Run LUKS2 fuzzer +`FUZZER_NAME` can be one of: `crypt2_load_fuzz`, `crypt2_load_proto_fuzz`, `crypt2_load_proto_plain_json_fuzz` +``` +FUZZER_NAME="crypt2_load_proto_plain_json_fuzz" +sudo mkdir -p build/corpus/cryptsetup/$FUZZER_NAME +sudo python infra/helper.py run_fuzzer --corpus-dir build/corpus/cryptsetup/$FUZZER_NAME/ --sanitizer address cryptsetup $FUZZER_NAME '-jobs=8 -workers=8' +``` + +The output of the parallel threads will be written to `fuzz-<N>.log` (where `<N>` is the number of the process). +You can watch it using e.g.: +``` +tail -f build/out/cryptsetup/fuzz-* +``` + +Optionally, you can use experimental `fork` mode for parallelization and the output will be displayed directly on the terminal: +``` +sudo python infra/helper.py run_fuzzer --corpus-dir build/corpus/cryptsetup/$FUZZER_NAME/ --sanitizer address cryptsetup $FUZZER_NAME '-fork=8 ' +``` + +# Rebuild fuzz targets for coverage +``` +sudo python infra/helper.py build_fuzzers --sanitizer coverage cryptsetup +``` + +# Generate coverage report +``` +sudo python infra/helper.py coverage cryptsetup --no-corpus-download --fuzz-target $FUZZER_NAME +``` + +# Further information +For more details, you can look into the [Using fuzzing for Linux disk encryption tools](https://is.muni.cz/th/bum03/?lang=en) thesis. diff --git a/tests/fuzz/crypt2_load_fuzz.cc b/tests/fuzz/crypt2_load_fuzz.cc new file mode 100644 index 0000000..1251d72 --- /dev/null +++ b/tests/fuzz/crypt2_load_fuzz.cc @@ -0,0 +1,112 @@ +/* + * cryptsetup LUKS2 fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +extern "C" { +#define FILESIZE (16777216) +#include "src/cryptsetup.h" +#include <err.h> +#include "luks2/luks2.h" +#include "crypto_backend/crypto_backend.h" +#include "FuzzerInterface.h" + +static int calculate_checksum(const uint8_t* data, size_t size) { + struct crypt_hash *hd = NULL; + struct luks2_hdr_disk *hdr = NULL; + int hash_size; + uint64_t hdr_size1, hdr_size2; + int r = 0; + + /* primary header */ + if (sizeof(struct luks2_hdr_disk) > size) + return 0; + hdr = CONST_CAST(struct luks2_hdr_disk *) data; + + hdr_size1 = be64_to_cpu(hdr->hdr_size); + if (hdr_size1 > size) + return 0; + memset(&hdr->csum, 0, LUKS2_CHECKSUM_L); + if ((r = crypt_hash_init(&hd, "sha256"))) + goto out; + if ((r = crypt_hash_write(hd, CONST_CAST(char*) data, hdr_size1))) + goto out; + hash_size = crypt_hash_size("sha256"); + if (hash_size <= 0) { + r = 1; + goto out; + } + if ((r = crypt_hash_final(hd, (char*)&hdr->csum, (size_t)hash_size))) + goto out; + crypt_hash_destroy(hd); + + /* secondary header */ + if (hdr_size1 < sizeof(struct luks2_hdr_disk)) + hdr_size1 = sizeof(struct luks2_hdr_disk); + + if (hdr_size1 + sizeof(struct luks2_hdr_disk) > size) + return 0; + hdr = CONST_CAST(struct luks2_hdr_disk *) (data + hdr_size1); + + hdr_size2 = be64_to_cpu(hdr->hdr_size); + if (hdr_size2 > size || (hdr_size1 + hdr_size2) > size) + return 0; + + memset(&hdr->csum, 0, LUKS2_CHECKSUM_L); + if ((r = crypt_hash_init(&hd, "sha256"))) + goto out; + if ((r = crypt_hash_write(hd, (char*) hdr, hdr_size2))) + goto out; + if ((r = crypt_hash_final(hd, (char*)&hdr->csum, (size_t)hash_size))) + goto out; + +out: + if (hd) + crypt_hash_destroy(hd); + return r; +} + +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + int fd; + struct crypt_device *cd = NULL; + char name[] = "/tmp/test-script-fuzz.XXXXXX"; + + if (calculate_checksum(data, size)) + return 0; + + fd = mkostemp(name, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC); + if (fd == -1) + err(EXIT_FAILURE, "mkostemp() failed"); + + /* enlarge header */ + if (ftruncate(fd, FILESIZE) == -1) + goto out; + + if (write_buffer(fd, data, size) != (ssize_t)size) + goto out; + + if (crypt_init(&cd, name) == 0) + (void)crypt_load(cd, CRYPT_LUKS2, NULL); + crypt_free(cd); +out: + close(fd); + unlink(name); + return 0; +} +} diff --git a/tests/fuzz/crypt2_load_fuzz.dict b/tests/fuzz/crypt2_load_fuzz.dict new file mode 100644 index 0000000..fedf1a4 --- /dev/null +++ b/tests/fuzz/crypt2_load_fuzz.dict @@ -0,0 +1,130 @@ +# LUKS2 dictionary based on AFL dictionary for JSON +# ------------------------------------------------- +# JSON dictionary from https://github.com/google/AFL/blob/master/dictionaries/json.dict +# Inspired by a dictionary by Jakub Wilk <jwilk@jwilk.net> +# +# LUKS2 keywords by Daniel Zatovic + +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + +"\"\":0" +"//" +"/**/" + +"$ref" +"type" +"coordinates" +"@context" +"@id" + +"," +":" + +"1024" +"2048" +"4096" +"512" +"aegis128-random" +"aes-cbc:essiv:sha256" +"aes-xts-plain64" +"af" +"allow-discards" +"area" +"argon2i" +"argon2id" +"backup-final" +"backup-moved-segment" +"backup-previous" +"checksum" +"config" +"cpus" +"crypt" +"datashift" +"digest" +"digests" +"direction" +"encryption" +"flags" +"hash" +"in-reencryption" +"integrity" +"iterations" +"iv_tweak" +"journal" +"journal_encryption" +"journal_integrity" +"json_size" +"kdf" +"key_description" +"key_size" +"keyslots" +"keyslots_size" +"linear" +"luks2" +"luks2-keyring" +"LUKS\xBA\xBE" +"memory" +"mode" +"no-journal" +"none" +"no-read-workqueue" +"no-write-workqueue" +"offline-reencrypt" +"offset" +"online-reencrypt-v2" +"pbkdf2" +"priority" +"raw" +"reencrypt" +"requirements" +"salt" +"same-cpu-crypt" +"sector_size" +"segments" +"serpent-xts-plain64" +"shift_size" +"size" +"SKUL\xBA\xBE" +"stripes" +"submit-from-crypt-cpus" +"time" +"tokens" +"twofish-xts-plain64" diff --git a/tests/fuzz/crypt2_load_ondisk_fuzz.cc b/tests/fuzz/crypt2_load_ondisk_fuzz.cc new file mode 100644 index 0000000..9b5328d --- /dev/null +++ b/tests/fuzz/crypt2_load_ondisk_fuzz.cc @@ -0,0 +1,64 @@ +/* + * cryptsetup LUKS1, FileVault, BitLocker fuzz target + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +extern "C" { +#define FILESIZE (16777216) +#include "src/cryptsetup.h" +#include <err.h> +#include "luks1/luks.h" +#include "crypto_backend/crypto_backend.h" +#include "FuzzerInterface.h" + +void empty_log(int level, const char *msg, void *usrptr) {} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + int fd, r; + struct crypt_device *cd = NULL; + char name[] = "/tmp/test-script-fuzz.XXXXXX"; + + fd = mkostemp(name, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC); + if (fd == -1) + err(EXIT_FAILURE, "mkostemp() failed"); + + /* enlarge header */ + if (ftruncate(fd, FILESIZE) == -1) + goto out; + + if (write_buffer(fd, data, size) != (ssize_t) size) + goto out; + + crypt_set_log_callback(NULL, empty_log, NULL); + + if (crypt_init(&cd, name) == 0) { + r = crypt_load(cd, CRYPT_LUKS1, NULL); + if (r == 0) + goto out; + + r = crypt_load(cd, CRYPT_FVAULT2, NULL); + if (r == 0) + goto out; + + (void) crypt_load(cd, CRYPT_BITLK, NULL); + } +out: + crypt_free(cd); + close(fd); + unlink(name); + return 0; +} +} diff --git a/tests/fuzz/crypt2_load_ondisk_fuzz.dict b/tests/fuzz/crypt2_load_ondisk_fuzz.dict new file mode 100644 index 0000000..3923db5 --- /dev/null +++ b/tests/fuzz/crypt2_load_ondisk_fuzz.dict @@ -0,0 +1,9 @@ +"aegis128-random" +"aes-cbc:essiv:sha256" +"aes-xts-plain64" +"aes-lrv-plain64" +"twofish-xts-plain64" +"serpent-xts-plain64" +"whirpool" +"sha256" +"sha1" diff --git a/tests/fuzz/crypt2_load_proto_fuzz.cc b/tests/fuzz/crypt2_load_proto_fuzz.cc new file mode 100644 index 0000000..498c006 --- /dev/null +++ b/tests/fuzz/crypt2_load_proto_fuzz.cc @@ -0,0 +1,51 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "LUKS2.pb.h" +#include "proto_to_luks2_converter.h" +#include "libfuzzer/libfuzzer_macro.h" +#include "FuzzerInterface.h" + +extern "C" { +#include <libcryptsetup.h> +#include <err.h> +#include <fcntl.h> +#include <unistd.h> +} + +DEFINE_PROTO_FUZZER(const LUKS2_proto::LUKS2_both_headers &headers) { + struct crypt_device *cd = NULL; + char name[] = "/tmp/test-proto-fuzz.XXXXXX"; + int fd = mkostemp(name, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC); + + if (fd < 0) + err(EXIT_FAILURE, "mkostemp() failed"); + + LUKS2_proto::LUKS2ProtoConverter converter; + converter.convert(headers, fd); + + if (crypt_init(&cd, name) == 0) + (void)crypt_load(cd, CRYPT_LUKS2, NULL); + crypt_free(cd); + + close(fd); + unlink(name); +} diff --git a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc new file mode 100644 index 0000000..f3565ab --- /dev/null +++ b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc @@ -0,0 +1,51 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "LUKS2_plain_JSON.pb.h" +#include "plain_json_proto_to_luks2_converter.h" +#include "libfuzzer/libfuzzer_macro.h" +#include "FuzzerInterface.h" + +extern "C" { +#include <libcryptsetup.h> +#include <err.h> +#include <fcntl.h> +#include <unistd.h> +} + +DEFINE_PROTO_FUZZER(const json_proto::LUKS2_both_headers &headers) { + struct crypt_device *cd = NULL; + char name[] = "/tmp/test-proto-fuzz.XXXXXX"; + int fd = mkostemp(name, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC); + + if (fd < 0) + err(EXIT_FAILURE, "mkostemp() failed"); + + json_proto::LUKS2ProtoConverter converter; + converter.convert(headers, fd); + + if (crypt_init(&cd, name) == 0) + (void)crypt_load(cd, CRYPT_LUKS2, NULL); + crypt_free(cd); + + close(fd); + unlink(name); +} diff --git a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.dict b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.dict new file mode 100644 index 0000000..7d83151 --- /dev/null +++ b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.dict @@ -0,0 +1,72 @@ +# LUKS2 keywords by Daniel Zatovic + +"1024" +"2048" +"4096" +"512" +"aegis128-random" +"aes-cbc:essiv:sha256" +"aes-xts-plain64" +"af" +"allow-discards" +"area" +"argon2i" +"argon2id" +"backup-final" +"backup-moved-segment" +"backup-previous" +"checksum" +"config" +"cpus" +"crypt" +"datashift" +"digest" +"digests" +"direction" +"encryption" +"flags" +"hash" +"in-reencryption" +"integrity" +"iterations" +"iv_tweak" +"journal" +"journal_encryption" +"journal_integrity" +"json_size" +"kdf" +"key_description" +"key_size" +"keyslots" +"keyslots_size" +"linear" +"luks2" +"luks2-keyring" +"LUKS\xBA\xBE" +"memory" +"mode" +"no-journal" +"none" +"no-read-workqueue" +"no-write-workqueue" +"offline-reencrypt" +"offset" +"online-reencrypt-v2" +"pbkdf2" +"priority" +"raw" +"reencrypt" +"requirements" +"salt" +"same-cpu-crypt" +"sector_size" +"segments" +"serpent-xts-plain64" +"shift_size" +"size" +"SKUL\xBA\xBE" +"stripes" +"submit-from-crypt-cpus" +"time" +"tokens" +"twofish-xts-plain64" diff --git a/tests/fuzz/json_proto_converter.cc b/tests/fuzz/json_proto_converter.cc new file mode 100644 index 0000000..ed453be --- /dev/null +++ b/tests/fuzz/json_proto_converter.cc @@ -0,0 +1,87 @@ +// Copyright 2020 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "json_proto_converter.h" + +namespace json_proto { + +void JsonProtoConverter::AppendArray(const ArrayValue& array_value) { + data_ << '['; + bool need_comma = false; + for (const auto& value : array_value.value()) { + // Trailing comma inside of an array makes JSON invalid, avoid adding that. + if (need_comma) + data_ << ','; + else + need_comma = true; + + AppendValue(value); + } + data_ << ']'; +} + +void JsonProtoConverter::AppendNumber(const NumberValue& number_value) { + if (number_value.has_float_value()) { + data_ << number_value.float_value().value(); + } else if (number_value.has_exponent_value()) { + auto value = number_value.exponent_value(); + data_ << value.base(); + data_ << (value.use_uppercase() ? 'E' : 'e'); + data_ << value.exponent(); + } else if (number_value.has_exponent_frac_value()) { + auto value = number_value.exponent_value(); + data_ << value.base(); + data_ << (value.use_uppercase() ? 'E' : 'e'); + data_ << value.exponent(); + } else { + data_ << number_value.integer_value().value(); + } +} + +void JsonProtoConverter::AppendObject(const JsonObject& json_object) { + data_ << '{' << '"' << json_object.name() << '"' << ':'; + AppendValue(json_object.value()); + data_ << '}'; +} + +void JsonProtoConverter::AppendValue(const JsonValue& json_value) { + if (json_value.has_object_value()) { + AppendObject(json_value.object_value()); + } else if (json_value.has_array_value()) { + AppendArray(json_value.array_value()); + } else if (json_value.has_number_value()) { + AppendNumber(json_value.number_value()); + } else if (json_value.has_string_value()) { + data_ << '"' << json_value.string_value().value() << '"'; + } else if (json_value.has_boolean_value()) { + data_ << (json_value.boolean_value().value() ? "true" : "false"); + } else { + data_ << "null"; + } +} + +std::string JsonProtoConverter::Convert(const JsonObject& json_object) { + AppendObject(json_object); + return data_.str(); +} + +std::string JsonProtoConverter::Convert( + const json_proto::ArrayValue& json_array) { + AppendArray(json_array); + return data_.str(); +} + +} // namespace json_proto diff --git a/tests/fuzz/json_proto_converter.h b/tests/fuzz/json_proto_converter.h new file mode 100644 index 0000000..ca52d67 --- /dev/null +++ b/tests/fuzz/json_proto_converter.h @@ -0,0 +1,43 @@ +// Copyright 2020 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef JSON_PROTO_CONVERTER_H_ +#define JSON_PROTO_CONVERTER_H_ + +#include <sstream> +#include <string> + +#include "LUKS2_plain_JSON.pb.h" + +namespace json_proto { + +class JsonProtoConverter { + public: + std::string Convert(const json_proto::JsonObject&); + std::string Convert(const json_proto::ArrayValue&); + + private: + std::stringstream data_; + + void AppendArray(const json_proto::ArrayValue&); + void AppendNumber(const json_proto::NumberValue&); + void AppendObject(const json_proto::JsonObject&); + void AppendValue(const json_proto::JsonValue&); +}; + +} // namespace json_proto + +#endif // TESTING_LIBFUZZER_PROTO_JSON_PROTO_CONVERTER_H_ diff --git a/tests/fuzz/oss-fuzz-build.sh b/tests/fuzz/oss-fuzz-build.sh new file mode 100755 index 0000000..b2f643f --- /dev/null +++ b/tests/fuzz/oss-fuzz-build.sh @@ -0,0 +1,152 @@ +#!/usr/bin/env bash + +function in_oss_fuzz() +{ + test -n "$FUZZING_ENGINE" +} + +echo "Running cryptsetup OSS-Fuzz build script." +env +set -ex +PWD=$(pwd) + +export LC_CTYPE=C.UTF-8 + +export SRC=${SRC:-$PWD/build} +export OUT="${OUT:-$PWD/out}" +export DEPS_PATH=$SRC/static_lib_deps + +export PKG_CONFIG_PATH="$DEPS_PATH"/lib/pkgconfig + +export CC=${CC:-clang} +export CXX=${CXX:-clang++} +export LIB_FUZZING_ENGINE="${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}" + +SANITIZER="${SANITIZER:-address -fsanitize-address-use-after-scope}" +flags="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link" + +export CFLAGS="${CFLAGS:-$flags} -I$DEPS_PATH/include" +export CXXFLAGS="${CXXFLAGS:-$flags} -I$DEPS_PATH/include" +export LDFLAGS="${LDFLAGS-} -L$DEPS_PATH/lib" + +ENABLED_FUZZERS=${ENABLED_FUZZERS:-crypt2_load_fuzz crypt2_load_ondisk_fuzz crypt2_load_proto_plain_json_fuzz} + +mkdir -p $SRC +mkdir -p $OUT +mkdir -p $DEPS_PATH +cd $SRC + +LIBFUZZER_PATCH="$PWD/unpoison-mutated-buffers-from-libfuzzer.patch" +in_oss_fuzz && LIBFUZZER_PATCH="$PWD/cryptsetup/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch" + +in_oss_fuzz && apt-get update && apt-get install -y \ + make autoconf automake autopoint libtool pkg-config \ + sharutils gettext expect keyutils ninja-build \ + bison + +[ ! -d zlib ] && git clone --depth 1 https://github.com/madler/zlib.git +[ ! -d xz ] && git clone https://git.tukaani.org/xz.git +[ ! -d json-c ] && git clone --depth 1 https://github.com/json-c/json-c.git +[ ! -d lvm2 ] && git clone --depth 1 https://sourceware.org/git/lvm2.git +[ ! -d popt ] && git clone --depth 1 https://github.com/rpm-software-management/popt.git +[ ! -d libprotobuf-mutator ] && git clone --depth 1 https://github.com/google/libprotobuf-mutator.git \ + && [ "$SANITIZER" == "memory" ] && ( cd libprotobuf-mutator; patch -p1 < $LIBFUZZER_PATCH ) +[ ! -d openssl ] && git clone --depth 1 https://github.com/openssl/openssl +[ ! -d util-linux ] && git clone --depth 1 https://github.com/util-linux/util-linux +[ ! -d cryptsetup_fuzzing ] && git clone --depth 1 https://gitlab.com/cryptsetup/cryptsetup_fuzzing.git + +cd openssl +./Configure --prefix="$DEPS_PATH" --libdir=lib no-shared no-module no-asm +make build_generated +make -j libcrypto.a +make install_dev +cd .. + +cd util-linux +./autogen.sh +./configure --prefix="$DEPS_PATH" --enable-static --disable-shared -disable-all-programs --enable-libuuid --enable-libblkid +make -j +make install +cd .. + +cd zlib +./configure --prefix="$DEPS_PATH" --static +make -j +make install +cd .. + +cd xz +./autogen.sh --no-po4a +./configure --prefix="$DEPS_PATH" --enable-static --disable-shared +make -j +make install +cd .. + +cd json-c +mkdir -p build +rm -fr build/* +cd build +cmake .. -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON +make -j +make install +cd ../.. + +cd lvm2 +./configure --prefix="$DEPS_PATH" --enable-static_link --disable-udev_sync --enable-pkgconfig --disable-selinux +make -j libdm.device-mapper +# build of dmsetup.static is broken +# make install_device-mapper +cp ./libdm/ioctl/libdevmapper.a "$DEPS_PATH"/lib/ +cp ./libdm/libdevmapper.h "$DEPS_PATH"/include/ +cp ./libdm/libdevmapper.pc "$PKG_CONFIG_PATH" +cd .. + +cd popt +# --no-undefined is incompatible with sanitizers +sed -i -e 's/-Wl,--no-undefined //' src/CMakeLists.txt +mkdir -p build +rm -fr build/* +cd build +cmake .. -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" -DBUILD_SHARED_LIBS=OFF +make -j +make install +cd ../.. + +cd libprotobuf-mutator +mkdir -p build +rm -fr build/* +cd build +cmake .. -GNinja \ + -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" \ + -DPKG_CONFIG_PATH="$PKG_CONFIG_PATH" \ + -DLIB_PROTO_MUTATOR_TESTING=OFF \ + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON +ninja +ninja install +cd external.protobuf; +cp -Rf bin lib include "$DEPS_PATH"; +cd ../../.. + +if in_oss_fuzz; then + mkdir -p cryptsetup/tests/fuzz/build + ln -s ../../../../static_lib_deps cryptsetup/tests/fuzz/build/static_lib_deps + cd cryptsetup +else + cd ../../.. +fi +./autogen.sh +./configure --enable-static --disable-asciidoc --disable-ssh-token --disable-udev --disable-selinux --with-crypto_backend=openssl --disable-shared --enable-fuzz-targets +make clean +make -j fuzz-targets + +for fuzzer in $ENABLED_FUZZERS; do + cp tests/fuzz/$fuzzer $OUT + cp $SRC/cryptsetup_fuzzing/${fuzzer}_seed_corpus.zip $OUT + + # optionally copy the dictionary if it exists + if [ -e tests/fuzz/${fuzzer}.dict ]; then + cp tests/fuzz/${fuzzer}.dict $OUT + fi +done + +cd $PWD diff --git a/tests/fuzz/plain_json_proto_to_luks2.cc b/tests/fuzz/plain_json_proto_to_luks2.cc new file mode 100644 index 0000000..8c56c15 --- /dev/null +++ b/tests/fuzz/plain_json_proto_to_luks2.cc @@ -0,0 +1,75 @@ +/* + * cryptsetup LUKS2 protobuf to image converter + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <iostream> +#include <string> + +#include <fcntl.h> +#include <unistd.h> + +#include <google/protobuf/text_format.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + +#include "plain_json_proto_to_luks2_converter.h" + +using namespace json_proto; + +int main(int argc, char *argv[]) { + LUKS2_both_headers headers; + LUKS2ProtoConverter converter; + int fd; + + std::string out_img_name; + + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " <LUKS2 proto>\n"; + return EXIT_FAILURE; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + std::cerr << "Failed to open " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + google::protobuf::io::FileInputStream fileInput(fd); + + if (!google::protobuf::TextFormat::Parse(&fileInput, &headers)) { + std::cerr << "Failed to parse protobuf " << argv[1] << std::endl; + close(fd); + return EXIT_FAILURE; + } + close(fd); + + out_img_name = argv[1]; + out_img_name += ".img"; + + fd = open(out_img_name.c_str(), O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC|O_TRUNC, 0644); + if (fd < 0) { + std::cerr << "Failed to open output file " << out_img_name << std::endl; + return EXIT_FAILURE; + } + converter.set_write_headers_only(false); + converter.convert(headers, fd); + + close(fd); + return EXIT_SUCCESS; +} diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.cc b/tests/fuzz/plain_json_proto_to_luks2_converter.cc new file mode 100644 index 0000000..823c0c5 --- /dev/null +++ b/tests/fuzz/plain_json_proto_to_luks2_converter.cc @@ -0,0 +1,153 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "plain_json_proto_to_luks2_converter.h" +#include "json_proto_converter.h" + +extern "C" { +#include "src/cryptsetup.h" +#include "luks2/luks2.h" +#include <err.h> +} + +namespace json_proto { + +void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_proto, int fd, uint64_t offset, uint64_t seqid, const std::string &json_text) { + struct luks2_hdr_disk hdr = {}; + int r; + + if (hd) + crypt_hash_destroy(hd); + if (crypt_hash_init(&hd, "sha256")) + err(EXIT_FAILURE, "crypt_hash_init failed"); + + + r = lseek(fd, offset, SEEK_SET); + if (r == -1) + err(EXIT_FAILURE, "lseek failed"); + + switch (header_proto.magic()) { + case INVALID: + memset(&hdr.magic, 0, LUKS2_MAGIC_L); + break; + case FIRST: + memcpy(&hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L); + break; + case SECOND: + memcpy(&hdr.magic, LUKS2_MAGIC_2ND, LUKS2_MAGIC_L); + break; + } + hdr.version = cpu_to_be16(header_proto.version()); + hdr.hdr_size = cpu_to_be64(header_proto.hdr_size()); + hdr.seqid = cpu_to_be64(seqid); + strncpy(hdr.checksum_alg, "sha256", LUKS2_CHECKSUM_ALG_L); + hdr.checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0'; + strncpy(hdr.uuid, "af7f64ea-3233-4581-946b-6187d812841e", LUKS2_UUID_L); + memset(hdr.salt, 1, LUKS2_SALT_L); + + + if (header_proto.has_selected_offset()) + hdr.hdr_offset = cpu_to_be64(header_proto.selected_offset()); + else + hdr.hdr_offset = cpu_to_be64(offset); + + if (write_buffer(fd, &hdr, LUKS2_HDR_BIN_LEN) != LUKS2_HDR_BIN_LEN) + err(EXIT_FAILURE, "write_buffer failed"); + if (crypt_hash_write(hd, (char*)&hdr, LUKS2_HDR_BIN_LEN)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + + size_t hdr_json_area_len = header_proto.hdr_size() - LUKS2_HDR_BIN_LEN; + uint8_t csum[LUKS2_CHECKSUM_L]; + + size_t write_size = json_text.length() > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text.length(); + if (write_buffer(fd, json_text.c_str(), write_size) != (ssize_t)write_size) + err(EXIT_FAILURE, "write_buffer failed"); + if (crypt_hash_write(hd, json_text.c_str(), write_size)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + + for (size_t i = 0; i < (hdr_json_area_len - write_size); i++) { + if (crypt_hash_write(hd, "\0", 1)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + } + + if (header_proto.use_correct_checksum()) { + if (lseek(fd, offset + offsetof(luks2_hdr_disk, csum), SEEK_SET) == -1) + err(EXIT_FAILURE, "lseek failed"); + + int hash_size = crypt_hash_size("sha256"); + if (hash_size <= 0) + err(EXIT_FAILURE, "crypt_hash_size failed"); + + if (crypt_hash_final(hd, (char*)csum, (size_t)hash_size)) + err(EXIT_FAILURE, "crypt_hash_final failed"); + if (write_buffer(fd, csum, hash_size) != hash_size) + err(EXIT_FAILURE, "write_buffer failed"); + } +} + +void LUKS2ProtoConverter::set_write_headers_only(bool headers_only) { + write_headers_only = headers_only; +} + +void LUKS2ProtoConverter::convert(const LUKS2_both_headers &headers, int fd) { + uint64_t primary_seqid, secondary_seqid; + int result; + + size_t out_size = headers.primary_header().hdr_size() + headers.secondary_header().hdr_size(); + + if (!write_headers_only) + out_size += KEYSLOTS_SIZE + DATA_SIZE; + + result = ftruncate(fd, out_size); + if (result == -1) + err(EXIT_FAILURE, "truncate failed"); + + result = lseek(fd, 0, SEEK_SET); + if (result == -1) + err(EXIT_FAILURE, "lseek failed"); + + switch (headers.seqid()) { + case EQUAL: + primary_seqid = 1; + secondary_seqid = 1; + break; + case PRIMARY_GREATER: + primary_seqid = 2; + secondary_seqid = 1; + break; + case SECONDARY_GREATER: + primary_seqid = 1; + secondary_seqid = 2; + break; + } + + JsonProtoConverter converter; + std::string json_text = converter.Convert(headers.json_area()); + + emit_luks2_binary_header(headers.primary_header(), fd, 0, primary_seqid, json_text); + emit_luks2_binary_header(headers.secondary_header(), fd, headers.primary_header().hdr_size(), secondary_seqid, json_text); +} + +LUKS2ProtoConverter::~LUKS2ProtoConverter() { + if (hd) + crypt_hash_destroy(hd); +} +} // namespace LUKS2_proto diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.h b/tests/fuzz/plain_json_proto_to_luks2_converter.h new file mode 100644 index 0000000..7decf9f --- /dev/null +++ b/tests/fuzz/plain_json_proto_to_luks2_converter.h @@ -0,0 +1,58 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef LUKS2_PROTO_CONVERTER_H_ +#define LUKS2_PROTO_CONVERTER_H_ + +#include <sstream> +#include <string> +#include <json-c/json.h> + +#include "LUKS2_plain_JSON.pb.h" +extern "C" { +#include "crypto_backend/crypto_backend.h" +} + +namespace json_proto { + +class LUKS2ProtoConverter { + public: + ~LUKS2ProtoConverter(); + void create_jobj(const LUKS2_both_headers &headers, uint64_t hdr_size); + void convert(const LUKS2_both_headers &headers, int fd); + void create_jobj(const LUKS2_both_headers &headers); + void emit_luks2_binary_header(const LUKS2_header &header_proto, int fd, uint64_t offset, uint64_t seqid, const std::string &json_text); + + void set_write_headers_only(bool headers_only); + + const uint8_t *get_out_buffer(); + size_t get_out_size(); + + static const uint64_t KEYSLOTS_SIZE = 3 * 1024 * 1024; + static const uint64_t DATA_SIZE = 16 * 1024 * 1024; + private: + bool write_headers_only = false; + struct crypt_hash *hd = NULL; +}; + +} // namespace LUKS2_proto + +#endif // LUKS2_PROTO_CONVERTER_H_ diff --git a/tests/fuzz/proto_to_luks2.cc b/tests/fuzz/proto_to_luks2.cc new file mode 100644 index 0000000..4a27cad --- /dev/null +++ b/tests/fuzz/proto_to_luks2.cc @@ -0,0 +1,75 @@ +/* + * cryptsetup LUKS2 protobuf to image converter + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <iostream> +#include <string> + +#include <fcntl.h> +#include <unistd.h> + +#include <google/protobuf/text_format.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + +#include "proto_to_luks2_converter.h" + +using namespace LUKS2_proto; + +int main(int argc, char *argv[]) { + LUKS2_both_headers headers; + LUKS2ProtoConverter converter; + int fd; + + std::string out_img_name; + + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " <LUKS2 proto>\n"; + return EXIT_FAILURE; + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + std::cerr << "Failed to open " << argv[1] << std::endl; + return EXIT_FAILURE; + } + + google::protobuf::io::FileInputStream fileInput(fd); + + if (!google::protobuf::TextFormat::Parse(&fileInput, &headers)) { + std::cerr << "Failed to parse protobuf " << argv[1] << std::endl; + close(fd); + return EXIT_FAILURE; + } + close(fd); + + out_img_name = argv[1]; + out_img_name += ".img"; + + fd = open(out_img_name.c_str(), O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC|O_TRUNC, 0644); + if (fd < 0) { + std::cerr << "Failed to open output file " << out_img_name << std::endl; + return EXIT_FAILURE; + } + converter.set_write_headers_only(false); + converter.convert(headers, fd); + + close(fd); + return EXIT_SUCCESS; +} diff --git a/tests/fuzz/proto_to_luks2_converter.cc b/tests/fuzz/proto_to_luks2_converter.cc new file mode 100644 index 0000000..96a70b7 --- /dev/null +++ b/tests/fuzz/proto_to_luks2_converter.cc @@ -0,0 +1,604 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "proto_to_luks2_converter.h" +#include <iostream> + +extern "C" { +#include "src/cryptsetup.h" +#include "luks2/luks2.h" +#include <err.h> +} + +namespace LUKS2_proto { + +std::string LUKS2ProtoConverter::string_uint64_to_string(const string_uint64 &str_u64) { + std::ostringstream os; + + if (str_u64.negative()) + os << "-"; + + if (str_u64.has_uint_num()) + os << str_u64.uint_num(); + else if (str_u64.has_string_num()) + os << str_u64.string_num(); + + return os.str(); +} + +std::string LUKS2ProtoConverter::object_id_to_string(const object_id &oid) { + std::ostringstream os; + + if (oid.has_int_id()) { + os << (oid.int_id() % 33) - 16; + } else if (oid.has_string_id()) { + os << oid.string_id(); + } + + return os.str(); +} + +std::string LUKS2ProtoConverter::hash_algorithm_to_string(const hash_algorithm type) { + switch (type) { + case HASH_ALG_SHA1: + return "sha1"; + case HASH_ALG_SHA256: + return "sha256"; + } +} + +std::string LUKS2ProtoConverter::keyslot_area_type_to_string(const keyslot_area_type type) { + switch (type) { + case KEYSLOT_AREA_TYPE_RAW: + return "raw"; + case KEYSLOT_AREA_TYPE_NONE: + return "none"; + case KEYSLOT_AREA_TYPE_JOURNAL: + return "journal"; + case KEYSLOT_AREA_TYPE_CHECKSUM: + return "checksum"; + case KEYSLOT_AREA_TYPE_DATASHIFT: + return "datashift"; + } +} + +void LUKS2ProtoConverter::generate_keyslot_area(struct json_object *jobj_area, const keyslot_area_description &keyslot_area_desc) { + // mandatory fields + if (keyslot_area_desc.has_type()) + json_object_object_add(jobj_area, "type", json_object_new_string(keyslot_area_type_to_string(keyslot_area_desc.type()).c_str())); + if (keyslot_area_desc.has_offset()) + json_object_object_add(jobj_area, "offset", json_object_new_string(string_uint64_to_string(keyslot_area_desc.offset()).c_str())); + if (keyslot_area_desc.has_size()) + json_object_object_add(jobj_area, "size", json_object_new_string(string_uint64_to_string(keyslot_area_desc.size()).c_str())); + + // raw type fields + if (keyslot_area_desc.has_encryption()) + json_object_object_add(jobj_area, "encryption", json_object_new_string(keyslot_area_desc.encryption().c_str())); + if (keyslot_area_desc.has_key_size()) + json_object_object_add(jobj_area, "key_size", json_object_new_int(keyslot_area_desc.key_size())); + + // checksum type fields + if (keyslot_area_desc.has_hash()) + json_object_object_add(jobj_area, "hash", json_object_new_string(hash_algorithm_to_string(keyslot_area_desc.hash()).c_str())); + if (keyslot_area_desc.has_sector_size()) + json_object_object_add(jobj_area, "sector_size", json_object_new_int(keyslot_area_desc.sector_size())); + + // datashift type fields + if (keyslot_area_desc.has_shift_size()) + json_object_object_add(jobj_area, "shift_size", json_object_new_string(string_uint64_to_string(keyslot_area_desc.shift_size()).c_str())); +} + +std::string LUKS2ProtoConverter::keyslot_kdf_type_to_string(const keyslot_kdf_type type) { + switch (type) { + case KEYSLOT_KDF_TYPE_PBKDF2: + return "pbkdf2"; + case KEYSLOT_KDF_TYPE_ARGON2I: + return "argon2i"; + case KEYSLOT_KDF_TYPE_ARGON2ID: + return "argon2id"; + } +} + +void LUKS2ProtoConverter::generate_keyslot_kdf(struct json_object *jobj_kdf, const keyslot_kdf_description &keyslot_kdf_desc) { + // mandatory fields + if (keyslot_kdf_desc.has_type()) + json_object_object_add(jobj_kdf, "type", json_object_new_string(keyslot_kdf_type_to_string(keyslot_kdf_desc.type()).c_str())); + + if (keyslot_kdf_desc.has_salt()) + json_object_object_add(jobj_kdf, "salt", json_object_new_string(keyslot_kdf_desc.salt().c_str())); + else + json_object_object_add(jobj_kdf, "salt", json_object_new_string("6vz4xK7cjan92rDA5JF8O6Jk2HouV0O8DMB6GlztVk=")); + + // pbkdf2 type + if (keyslot_kdf_desc.has_hash()) + json_object_object_add(jobj_kdf, "hash", json_object_new_string(hash_algorithm_to_string(keyslot_kdf_desc.hash()).c_str())); + if (keyslot_kdf_desc.has_iterations()) + json_object_object_add(jobj_kdf, "iterations", json_object_new_int(keyslot_kdf_desc.iterations())); + + // argon2i and argon2id types + if (keyslot_kdf_desc.has_time()) + json_object_object_add(jobj_kdf, "time", json_object_new_int(keyslot_kdf_desc.time())); + if (keyslot_kdf_desc.has_memory()) + json_object_object_add(jobj_kdf, "memory", json_object_new_int(keyslot_kdf_desc.memory())); + if (keyslot_kdf_desc.has_cpus()) + json_object_object_add(jobj_kdf, "cpus", json_object_new_int(keyslot_kdf_desc.cpus())); +} + +std::string LUKS2ProtoConverter::keyslot_af_type_to_string(const keyslot_af_type type) { + switch (type) { + case KEYSLOT_AF_TYPE_LUKS1: + return "luks1"; + } +} + +void LUKS2ProtoConverter::generate_keyslot_af(struct json_object *jobj_af, const keyslot_af_description &keyslot_af_desc) { + if (keyslot_af_desc.has_type()) + json_object_object_add(jobj_af, "type", json_object_new_string(keyslot_af_type_to_string(keyslot_af_desc.type()).c_str())); + if (keyslot_af_desc.has_stripes()) + json_object_object_add(jobj_af, "stripes", json_object_new_int(keyslot_af_desc.stripes())); + if (keyslot_af_desc.has_hash()) + json_object_object_add(jobj_af, "hash", json_object_new_string(hash_algorithm_to_string(keyslot_af_desc.hash()).c_str())); +} + +std::string LUKS2ProtoConverter::keyslot_type_to_string(const keyslot_type type) { + switch (type) { + case KEYSLOT_TYPE_LUKS2: + return "luks2"; + case KEYSLOT_TYPE_REENCRYPT: + return "reencrypt"; + case KEYSLOT_TYPE_PLACEHOLDER: + return "placeholder"; + } +} + +std::string LUKS2ProtoConverter::reencrypt_keyslot_mode_to_string(const reencrypt_keyslot_mode mode) { + switch (mode) { + case MODE_REENCRYPT: + return "reencrypt"; + case MODE_ENCRYPT: + return "encrypt"; + case MODE_DECRYPT: + return "decrypt"; + } +} + +std::string LUKS2ProtoConverter::reencrypt_keyslot_direction_to_string(const reencrypt_keyslot_direction direction) { + switch (direction) { + case DIRECTION_FORWARD: + return "forward"; + case DIRECTION_BACKWARD: + return "backward"; + } +} + +void LUKS2ProtoConverter::generate_keyslot(struct json_object *jobj_keyslots, const keyslot_description &keyslot_desc) { + struct json_object *jobj_keyslot, *jobj_area, *jobj_kdf, *jobj_af; + + jobj_keyslot = json_object_new_object(); + if (keyslot_desc.has_type()) + json_object_object_add(jobj_keyslot, "type", json_object_new_string(keyslot_type_to_string(keyslot_desc.type()).c_str())); + if (keyslot_desc.has_key_size()) + json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(keyslot_desc.key_size())); + if (keyslot_desc.has_priority()) + json_object_object_add(jobj_keyslot, "priority", json_object_new_int(keyslot_desc.priority())); + if (keyslot_desc.has_mode()) + json_object_object_add(jobj_keyslot, "mode", json_object_new_int(keyslot_desc.mode())); + if (keyslot_desc.has_direction()) + json_object_object_add(jobj_keyslot, "direction", json_object_new_int(keyslot_desc.direction())); + + /* Area object */ + if (keyslot_desc.has_area()) { + jobj_area = json_object_new_object(); + generate_keyslot_area(jobj_area, keyslot_desc.area()); + json_object_object_add(jobj_keyslot, "area", jobj_area); + } + + /* KDF object */ + if (keyslot_desc.has_kdf()) { + jobj_kdf = json_object_new_object(); + generate_keyslot_kdf(jobj_kdf, keyslot_desc.kdf()); + json_object_object_add(jobj_keyslot, "kdf", jobj_kdf); + } + + /* AF object */ + if (keyslot_desc.has_af()) { + jobj_af = json_object_new_object(); + generate_keyslot_af(jobj_af, keyslot_desc.af()); + json_object_object_add(jobj_keyslot, "af", jobj_af); + } + + json_object_object_add(jobj_keyslots, object_id_to_string(keyslot_desc.oid()).c_str(), jobj_keyslot); +} + +void LUKS2ProtoConverter::generate_token(struct json_object *jobj_tokens, const token_description &token_desc) { + struct json_object *jobj_token, *jobj_keyslots; + jobj_token = json_object_new_object(); + + if (token_desc.has_type()) + json_object_object_add(jobj_token, "type", json_object_new_string(token_desc.type().c_str())); + + if (token_desc.has_key_description()) + json_object_object_add(jobj_token, "key_description", json_object_new_string(token_desc.key_description().c_str())); + + if (!token_desc.keyslots().empty()) { + jobj_keyslots = json_object_new_array(); + + for (const object_id& oid : token_desc.keyslots()) { + json_object_array_add(jobj_keyslots, + json_object_new_string(object_id_to_string(oid).c_str())); + } + + /* Replace or add new keyslots array */ + json_object_object_add(jobj_token, "keyslots", jobj_keyslots); + } + + json_object_object_add(jobj_tokens, object_id_to_string(token_desc.oid()).c_str(), jobj_token); +} + +void LUKS2ProtoConverter::generate_digest(struct json_object *jobj_digests, const digest_description &digest_desc) { + struct json_object *jobj_digest, *jobj_keyslots, *jobj_segments; + + jobj_digest = json_object_new_object(); + + if (digest_desc.has_type()) + json_object_object_add(jobj_digest, "type", json_object_new_string(keyslot_kdf_type_to_string(digest_desc.type()).c_str())); + + if (!digest_desc.keyslots().empty()) { + jobj_keyslots = json_object_new_array(); + + for (const object_id& oid : digest_desc.keyslots()) { + json_object_array_add(jobj_keyslots, + json_object_new_string(object_id_to_string(oid).c_str())); + } + + /* Replace or add new keyslots array */ + json_object_object_add(jobj_digest, "keyslots", jobj_keyslots); + } + + if (!digest_desc.segments().empty()) { + jobj_segments = json_object_new_array(); + + for (const object_id& oid : digest_desc.segments()) { + json_object_array_add(jobj_segments, + json_object_new_string(object_id_to_string(oid).c_str())); + } + + /* Replace or add new segments array */ + json_object_object_add(jobj_digest, "segments", jobj_segments); + } + + if (digest_desc.has_salt()) + json_object_object_add(jobj_digest, "salt", json_object_new_string(digest_desc.salt().c_str())); + if (digest_desc.has_digest()) + json_object_object_add(jobj_digest, "digest", json_object_new_string(digest_desc.digest().c_str())); + if (digest_desc.has_hash()) + json_object_object_add(jobj_digest, "hash", json_object_new_string(hash_algorithm_to_string(digest_desc.hash()).c_str())); + if (digest_desc.has_iterations()) + json_object_object_add(jobj_digest, "iterations", json_object_new_int(digest_desc.iterations())); + + json_object_object_add(jobj_digests, object_id_to_string(digest_desc.oid()).c_str(), jobj_digest); +} + +std::string LUKS2ProtoConverter::segment_type_to_string(segment_type type) { + switch (type) { + case SEGMENT_TYPE_LINEAR: + return "linear"; + case SEGMENT_TYPE_CRYPT: + return "crypt"; + } +} + +std::string LUKS2ProtoConverter::segment_flag_to_string(segment_flag flag) { + switch (flag) { + case IN_REENCRYPTION: + return "in-reencryption"; + case BACKUP_FINAL: + return "backup-final"; + case BACKUP_PREVIOUS: + return "backup-previous"; + case BACKUP_MOVED_SEGMENT: + return "backup-moved-segment"; + } +} + +void LUKS2ProtoConverter::generate_segment_integrity(struct json_object *jobj_integrity, const segment_integrity_description &segment_integrity_desc) { + if (segment_integrity_desc.has_type()) + json_object_object_add(jobj_integrity, "type", json_object_new_string(segment_integrity_desc.type().c_str())); + if (segment_integrity_desc.has_journal_encryption()) + json_object_object_add(jobj_integrity, "journal_encryption", json_object_new_string(segment_integrity_desc.journal_encryption().c_str())); + if (segment_integrity_desc.has_journal_integrity()) + json_object_object_add(jobj_integrity, "journal_integrity", json_object_new_string(segment_integrity_desc.journal_integrity().c_str())); +} + +void LUKS2ProtoConverter::generate_segment(struct json_object *jobj_segments, const segment_description &segment_desc) { + json_object *jobj_flags, *jobj_integrity; + json_object *jobj_segment = json_object_new_object(); + + if (segment_desc.has_type()) + json_object_object_add(jobj_segment, "type", json_object_new_string(segment_type_to_string(segment_desc.type()).c_str())); + + if (segment_desc.has_offset()) + json_object_object_add(jobj_segment, "offset", json_object_new_string(string_uint64_to_string(segment_desc.offset()).c_str())); + if (segment_desc.has_size()) + json_object_object_add(jobj_segment, "size", json_object_new_string(string_uint64_to_string(segment_desc.size()).c_str())); + + if (!segment_desc.flags().empty()) { + jobj_flags = json_object_new_array(); + + for (const int flag : segment_desc.flags()) { + json_object_array_add(jobj_flags, + json_object_new_string(segment_flag_to_string(segment_flag(flag)).c_str())); + } + + /* Replace or add new flags array */ + json_object_object_add(jobj_segment, "flags", jobj_flags); + } + + if (segment_desc.has_iv_tweak()) + json_object_object_add(jobj_segment, "iv_tweak", json_object_new_string(string_uint64_to_string(segment_desc.iv_tweak()).c_str())); + if (segment_desc.has_encryption()) + json_object_object_add(jobj_segment, "encryption", json_object_new_string(segment_desc.encryption().c_str())); + if (segment_desc.has_sector_size()) + json_object_object_add(jobj_segment, "sector_size", json_object_new_int(segment_desc.sector_size())); + + if (segment_desc.has_integrity()) { + jobj_integrity = json_object_new_object(); + generate_segment_integrity(jobj_integrity, segment_desc.integrity()); + json_object_object_add(jobj_segment, "integrity", jobj_integrity); + } + + json_object_object_add(jobj_segments, object_id_to_string(segment_desc.oid()).c_str(), jobj_segment); +} + +void LUKS2ProtoConverter::create_jobj(const LUKS2_both_headers &headers) { + json_object *jobj_keyslots = NULL; + json_object *jobj_digests = NULL; + json_object *jobj_segments = NULL; + json_object *jobj_tokens = NULL; + + const json_area_description &json_desc = headers.json_area(); + + jobj = json_object_new_object(); + if (!jobj) + return; + + jobj_keyslots = json_object_new_object(); + for (const keyslot_description &keyslot_desc : json_desc.keyslots()) { + generate_keyslot(jobj_keyslots, keyslot_desc); + } + json_object_object_add(jobj, "keyslots", jobj_keyslots); + + jobj_digests = json_object_new_object(); + for (const digest_description &digest_desc : json_desc.digests()) { + generate_digest(jobj_digests, digest_desc); + } + json_object_object_add(jobj, "digests", jobj_digests); + + jobj_segments = json_object_new_object(); + for (const segment_description &segment_desc : json_desc.segments()) { + generate_segment(jobj_segments, segment_desc); + } + json_object_object_add(jobj, "segments", jobj_segments); + + jobj_tokens = json_object_new_object(); + for (const token_description &token_desc : json_desc.tokens()) { + generate_token(jobj_tokens, token_desc); + } + json_object_object_add(jobj, "tokens", jobj_tokens); + + if (json_desc.has_config()) { + uint64_t hdr_size = json_desc.config().use_primary_hdr_size() ? headers.primary_header().hdr_size() : headers.secondary_header().hdr_size(); + generate_config(json_desc.config(), hdr_size - LUKS2_HDR_BIN_LEN, KEYSLOTS_SIZE); + } +} + +void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_proto, int fd, uint64_t offset, uint64_t seqid) { + struct luks2_hdr_disk hdr = {}; + int r; + + if (hd) + crypt_hash_destroy(hd); + if (crypt_hash_init(&hd, "sha256")) + err(EXIT_FAILURE, "crypt_hash_init failed"); + + + r = lseek(fd, offset, SEEK_SET); + if (r == -1) + err(EXIT_FAILURE, "lseek failed"); + + switch (header_proto.magic()) { + case INVALID: + memset(&hdr.magic, 0, LUKS2_MAGIC_L); + break; + case FIRST: + memcpy(&hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L); + break; + case SECOND: + memcpy(&hdr.magic, LUKS2_MAGIC_2ND, LUKS2_MAGIC_L); + break; + } + hdr.version = cpu_to_be16(header_proto.version()); + hdr.hdr_size = cpu_to_be64(header_proto.hdr_size()); + hdr.seqid = cpu_to_be64(seqid); + strncpy(hdr.checksum_alg, "sha256", LUKS2_CHECKSUM_ALG_L); + hdr.checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0'; + strncpy(hdr.uuid, "af7f64ea-3233-4581-946b-6187d812841e", LUKS2_UUID_L); + memset(hdr.salt, 1, LUKS2_SALT_L); + + + if (header_proto.has_selected_offset()) + hdr.hdr_offset = cpu_to_be64(header_proto.selected_offset()); + else + hdr.hdr_offset = cpu_to_be64(offset); + + if (write_buffer(fd, &hdr, LUKS2_HDR_BIN_LEN) != LUKS2_HDR_BIN_LEN) + err(EXIT_FAILURE, "write_buffer failed"); + if (crypt_hash_write(hd, (char*)&hdr, LUKS2_HDR_BIN_LEN)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + + size_t hdr_json_area_len = header_proto.hdr_size() - LUKS2_HDR_BIN_LEN; + size_t json_text_len; + const char *json_text; + uint8_t csum[LUKS2_CHECKSUM_L]; + + if (jobj) { + json_text = json_object_to_json_string_ext((struct json_object *)jobj, JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE); + if (!json_text || !*json_text) + err(EXIT_FAILURE, "json_object_to_json_string_ext failed"); + + json_text_len = strlen(json_text); + + size_t write_size = json_text_len > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text_len; + if (write_buffer(fd, json_text, write_size) != (ssize_t)write_size) + err(EXIT_FAILURE, "write_buffer failed"); + if (crypt_hash_write(hd, json_text, write_size)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + + for (size_t i = 0; i < (hdr_json_area_len - write_size); i++) { + if (crypt_hash_write(hd, "\0", 1)) + err(EXIT_FAILURE, "crypt_hash_write failed"); + } + } + + if (header_proto.use_correct_checksum()) { + if (lseek(fd, offset + offsetof(luks2_hdr_disk, csum), SEEK_SET) == -1) + err(EXIT_FAILURE, "lseek failed"); + + int hash_size = crypt_hash_size("sha256"); + if (hash_size <= 0) + err(EXIT_FAILURE, "crypt_hash_size failed"); + + if (crypt_hash_final(hd, (char*)csum, (size_t)hash_size)) + err(EXIT_FAILURE, "crypt_hash_final failed"); + if (write_buffer(fd, csum, hash_size) != hash_size) + err(EXIT_FAILURE, "write_buffer failed"); + } +} + +void LUKS2ProtoConverter::set_write_headers_only(bool headers_only) { + write_headers_only = headers_only; +} + +void LUKS2ProtoConverter::convert(const LUKS2_both_headers &headers, int fd) { + uint64_t primary_seqid, secondary_seqid; + int result; + + size_t out_size = headers.primary_header().hdr_size() + headers.secondary_header().hdr_size(); + + if (!write_headers_only) + out_size += KEYSLOTS_SIZE + DATA_SIZE; + + result = ftruncate(fd, out_size); + if (result == -1) + err(EXIT_FAILURE, "truncate failed"); + + result = lseek(fd, 0, SEEK_SET); + if (result == -1) + err(EXIT_FAILURE, "lseek failed"); + + switch (headers.seqid()) { + case EQUAL: + primary_seqid = 1; + secondary_seqid = 1; + break; + case PRIMARY_GREATER: + primary_seqid = 2; + secondary_seqid = 1; + break; + case SECONDARY_GREATER: + primary_seqid = 1; + secondary_seqid = 2; + break; + } + + create_jobj(headers); + emit_luks2_binary_header(headers.primary_header(), fd, 0, primary_seqid); + emit_luks2_binary_header(headers.secondary_header(), fd, headers.primary_header().hdr_size(), secondary_seqid); +} + +std::string LUKS2ProtoConverter::config_flag_to_string(config_flag flag) { + switch (flag) { + case CONFIG_FLAG_ALLOW_DISCARDS: + return "allow-discards"; + case CONFIG_FLAG_SAME_CPU_CRYPT: + return "same-cpu-crypt"; + case CONFIG_FLAG_SUBMIT_FROM_CRYPT_CPUS: + return "submit-from-crypt-cpus"; + case CONFIG_FLAG_NO_JOURNAL: + return "no-journal"; + case CONFIG_FLAG_NO_READ_WORKQUEUE: + return "no-read-workqueue"; + case CONFIG_FLAG_NO_WRITE_WORKQUEUE: + return "no-write-workqueue"; + } +} + +std::string LUKS2ProtoConverter::config_requirement_to_string(config_requirement requirement) { + switch (requirement) { + case CONFIG_REQUIREMENT_OFFLINE_REENCRYPT: + return "offline-reencrypt"; + case CONFIG_REQUIREMENT_ONLINE_REENCRYPT_V2: + return "online-reencrypt-v2"; + } +} + +void LUKS2ProtoConverter::generate_config(const config_description &config_desc, uint64_t json_size, uint64_t keyslots_size) { + json_object *jobj_config, *jobj_flags, *jobj_requirements, *jobj_mandatory; + jobj_config = json_object_new_object(); + + json_object_object_add(jobj_config, "json_size", json_object_new_string(std::to_string(json_size).c_str())); + json_object_object_add(jobj_config, "keyslots_size", json_object_new_string(std::to_string(keyslots_size).c_str())); + + if (!config_desc.config_flags().empty()) { + jobj_flags = json_object_new_array(); + + for (const int flag : config_desc.config_flags()) { + json_object_array_add(jobj_flags, + json_object_new_string(config_flag_to_string(config_flag(flag)).c_str())); + } + + /* Replace or add new flags array */ + json_object_object_add(jobj_config, "flags", jobj_flags); + } + + if (!config_desc.requirements().empty()) { + jobj_requirements = json_object_new_object(); + jobj_mandatory = json_object_new_array(); + + for (const int requirement : config_desc.requirements()) { + json_object_array_add(jobj_mandatory, + json_object_new_string(config_requirement_to_string(config_requirement(requirement)).c_str())); + } + + /* Replace or add new requirements array */ + json_object_object_add(jobj_requirements, "mandatory", jobj_mandatory); + json_object_object_add(jobj_config, "requirements", jobj_requirements); + } + + json_object_object_add(jobj, "config", jobj_config); +} + +LUKS2ProtoConverter::~LUKS2ProtoConverter() { + json_object_put(jobj); + if (hd) + crypt_hash_destroy(hd); +} +} // namespace LUKS2_proto diff --git a/tests/fuzz/proto_to_luks2_converter.h b/tests/fuzz/proto_to_luks2_converter.h new file mode 100644 index 0000000..9f926d0 --- /dev/null +++ b/tests/fuzz/proto_to_luks2_converter.h @@ -0,0 +1,91 @@ +/* + * cryptsetup LUKS2 custom mutator fuzz target + * + * Copyright (C) 2022-2023 Daniel Zatovic <daniel.zatovic@gmail.com> + * Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef LUKS2_PROTO_CONVERTER_H_ +#define LUKS2_PROTO_CONVERTER_H_ + +#include <sstream> +#include <string> +#include <json-c/json.h> + +#include "LUKS2.pb.h" +extern "C" { +#include "crypto_backend/crypto_backend.h" +} + +namespace LUKS2_proto { + +class LUKS2ProtoConverter { + public: + ~LUKS2ProtoConverter(); + std::string string_uint64_to_string(const string_uint64 &str_u64); + std::string hash_algorithm_to_string(const hash_algorithm type); + std::string object_id_to_string(const object_id &oid); + + std::string keyslot_area_type_to_string(const keyslot_area_type type); + std::string keyslot_kdf_type_to_string(const keyslot_kdf_type type); + std::string reencrypt_keyslot_mode_to_string(const reencrypt_keyslot_mode mode); + std::string keyslot_type_to_string(const keyslot_type type); + std::string reencrypt_keyslot_direction_to_string(const reencrypt_keyslot_direction direction); + std::string keyslot_af_type_to_string(const keyslot_af_type type); + + std::string config_flag_to_string(config_flag flag); + std::string config_requirement_to_string(config_requirement requirements); + + std::string segment_type_to_string(segment_type type); + std::string segment_flag_to_string(segment_flag flag); + + void generate_keyslot(struct json_object *jobj_keyslots, const keyslot_description &keyslot_desc); + void generate_keyslot_area(struct json_object *jobj_area, const keyslot_area_description &keyslot_area_desc); + void generate_keyslot_kdf(struct json_object *jobj_kdf, const keyslot_kdf_description &keyslot_kdf_desc); + void generate_keyslot_af(struct json_object *jobj_af, const keyslot_af_description &keyslot_af_desc); + + void generate_token(struct json_object *jobj_tokens, const token_description &token_desc); + + void generate_digest(struct json_object *jobj_digests, const digest_description &digest_desc); + + void generate_segment_integrity(struct json_object *jobj_integrity, const segment_integrity_description &segment_integrity_desc); + void generate_segment(struct json_object *jobj_segments, const segment_description &segment_desc); + + void generate_config(const config_description &config_desc, uint64_t json_size, uint64_t keyslots_size); + + void create_jobj(const LUKS2_both_headers &headers, uint64_t hdr_size); + void emit_luks2_binary_header(uint64_t offset, uint64_t seqid, bool is_primary, uint64_t hdr_size); + void convert(const LUKS2_both_headers &headers, int fd); + void create_jobj(const LUKS2_both_headers &headers); + void emit_luks2_binary_header(const LUKS2_header &header_proto, int fd, uint64_t offset, uint64_t seqid); + + void set_write_headers_only(bool headers_only); + + const uint8_t *get_out_buffer(); + size_t get_out_size(); + + static const uint64_t KEYSLOTS_SIZE = 3 * 1024 * 1024; + static const uint64_t DATA_SIZE = 16 * 1024 * 1024; + private: + bool write_headers_only = false; + struct crypt_hash *hd = NULL; + struct ::json_object *jobj = NULL; +}; + +} // namespace LUKS2_proto + +#endif // LUKS2_PROTO_CONVERTER_H_ diff --git a/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch b/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch new file mode 100644 index 0000000..1f48339 --- /dev/null +++ b/tests/fuzz/unpoison-mutated-buffers-from-libfuzzer.patch @@ -0,0 +1,29 @@ +diff --git a/src/libfuzzer/libfuzzer_mutator.cc b/src/libfuzzer/libfuzzer_mutator.cc +index 34d144c..b671fd4 100644 +--- a/src/libfuzzer/libfuzzer_mutator.cc ++++ b/src/libfuzzer/libfuzzer_mutator.cc +@@ -14,6 +14,8 @@ + + #include "src/libfuzzer/libfuzzer_mutator.h" + ++#include <sanitizer/msan_interface.h> ++ + #include <string.h> + + #include <algorithm> +@@ -64,6 +66,7 @@ template <class T> + T MutateValue(T v) { + size_t size = + LLVMFuzzerMutate(reinterpret_cast<uint8_t*>(&v), sizeof(v), sizeof(v)); ++ __msan_unpoison(reinterpret_cast<uint8_t*>(&v), size); + memset(reinterpret_cast<uint8_t*>(&v) + size, 0, sizeof(v) - size); + return v; + } +@@ -93,6 +96,7 @@ std::string Mutator::MutateString(const std::string& value, + result.resize(std::max(1, new_size)); + result.resize(LLVMFuzzerMutate(reinterpret_cast<uint8_t*>(&result[0]), + value.size(), result.size())); ++ __msan_unpoison(reinterpret_cast<uint8_t*>(&result[0]), result.size()); + return result; + } + diff --git a/tests/fvault2-compat-test b/tests/fvault2-compat-test new file mode 100755 index 0000000..45022d2 --- /dev/null +++ b/tests/fvault2-compat-test @@ -0,0 +1,134 @@ +#!/bin/bash + +[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +MAP=fvault2test +TST_DIR=fvault2-images + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + +[ -z "$srcdir" ] && srcdir="." + +function create_mapping() +{ + local image=$1 + local passphrase=$2 + echo -n "$passphrase" | "$CRYPTSETUP" open --type fvault2 --key-file - \ + "$image" "$MAP" +} + +function remove_mapping() +{ + [ -b "/dev/mapper/$MAP" ] && dmsetup remove --retry "$MAP" + rm -rf $TST_DIR +} + +function fail() +{ + [ -n "$1" ] && echo "$1" + echo " [FAILED]" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + remove_mapping + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + echo "Test skipped." + remove_mapping + exit 77 +} + +function produce_dump() +{ + "$CRYPTSETUP" fvault2Dump "$1" || fail +} + +function produce_dump_key() +{ + echo "$2" | "$CRYPTSETUP" fvault2Dump "$1" --dump-volume-key || fail +} + +function check_dump() +{ + local dump=$1 + local key=$2 + local exp_value=$3 + local regex="$key:\s*\(.*\)" + local value=$(echo "$dump" | sed -n "s|$regex|\1|p" | sed 's|\s*$||') + [ "$value" = "$exp_value" ] || fail \ + "$key check failed: expected \"$exp_value\", got \"$value\"" +} + +function check_uuid() +{ + local exp_uuid=$1 + local uuid=$(blkid -po value -s UUID "/dev/mapper/$MAP") + [ "$uuid" = "$exp_uuid" ] || fail \ + "UUID check failed: expected \"$exp_uuid\", got \"$uuid\"" +} + +function check_sha256() +{ + local exp_sum=$1 + local sum=$(sha256sum /dev/mapper/$MAP | head -c 64) + [ "$sum" = "$exp_sum" ] || fail \ + "SHA256 sum check failed: expected \"$exp_sum\", got \"$sum\"" +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +export LANG=C +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." + +if [ ! -d $TST_DIR ]; then + tar xJSf $srcdir/fvault2-images.tar.xz --no-same-owner 2>/dev/null || skip "Incompatible tar." +fi + +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + +echo "HEADER CHECK" +IMG="$TST_DIR/small" +PWD="heslo123" + +echo -n " $IMG" +dump=$(produce_dump $IMG) +check_dump "$dump" 'Physical volume UUID' fc52bfae-5a1f-4f9b-b3a6-f33303a0e401 +check_dump "$dump" 'Family UUID' 33a76caa-1481-4bc5-8d04-1ac1707c19c0 +check_dump "$dump" 'Logical volume offset' '67108864 [bytes]' +check_dump "$dump" 'Logical volume size' '167772160 [bytes]' +check_dump "$dump" 'PBKDF2 iterations' 204222 +check_dump "$dump" 'PBKDF2 salt' '2c 24 9e db 66 63 d6 fb cc 79 05 b7 a4 d7 27 52' +dump=$(produce_dump_key $IMG heslo123) +check_dump "$dump" 'Volume key' '20 73 4d 33 89 21 27 74 d7 61 0c 29 d7 32 88 09 16 f3 be 14 c4 b1 2a c7 aa f0 7e 5c cc 77 b3 19' +echo $PWD | $CRYPTSETUP open --type fvault2 --test-passphrase $IMG || fail +echo " [OK]" + +if [ $(id -u) != 0 ]; then + echo "WARNING: You must be root to run activation part of test, test skipped." + remove_mapping + exit 0 +fi + +echo "ACTIVATION CHECK" +echo -n " $IMG" +create_mapping $IMG heslo123 +check_uuid de124d8a-2164-394e-924f-8e28db0a09cb +check_sha256 2c662e36c0f7e2f5583e6a939bbcbdc660805692d0fccaa45ad4052beb3b8e18 +echo " [OK]" + +remove_mapping +exit 0 diff --git a/tests/fvault2-images.tar.xz b/tests/fvault2-images.tar.xz Binary files differnew file mode 100644 index 0000000..99fab77 --- /dev/null +++ b/tests/fvault2-images.tar.xz diff --git a/tests/generate-symbols-list b/tests/generate-symbols-list new file mode 100755 index 0000000..33a2e23 --- /dev/null +++ b/tests/generate-symbols-list @@ -0,0 +1,35 @@ +#!/bin/bash + +function fail() +{ + [ -n "$1" ] && echo "$1" + exit 2 +} + +function generate() { + local ver= + + while IFS= read -r line; do + local len=${#line} + + + if [ "${line:0:11}" = "CRYPTSETUP_" ]; then + local i=12 + while [ $i -lt $len ]; do + if [ "${line:$i:1}" = "{" ]; then + ver=${line:0:$i} + break + fi + i=$((i+1)) + done + elif [ "${line:0:6}" = "crypt_" -a -n "$ver" ]; then + printf 'CHECK_SYMBOL(%s, %s)\n' $line $ver + fi + done < <(tr -d '[:blank:];' < $1) +} + +test $# -ge 1 || fail "usage: $0 <symbol_file>" + +test -f $1 || fail "$1 is not a file." + +generate $1 diff --git a/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh b/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh index 3938f7b..a7d3147 100755 --- a/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh +++ b/tests/generators/generate-luks2-area-in-json-hdr-space-json0.img.sh @@ -14,15 +14,6 @@ # $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() { # make area 7 access the luks2 header space @@ -34,20 +25,12 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c --arg off $OFFS --arg len $LEN \ @@ -55,18 +38,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-argon2-leftover-params.img.sh b/tests/generators/generate-luks2-argon2-leftover-params.img.sh index 7f003a0..f0b74d7 100755 --- a/tests/generators/generate-luks2-argon2-leftover-params.img.sh +++ b/tests/generators/generate-luks2-argon2-leftover-params.img.sh @@ -14,15 +14,6 @@ # $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() { # add keyslot 1 to second digest @@ -32,40 +23,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_obj_len=$(jq -c -M '.keyslots."1".kdf | length' $TMPDIR/json_res0) test $((obj_len+2)) -eq $new_obj_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-correct-full-json0.img.sh b/tests/generators/generate-luks2-correct-full-json0.img.sh index f32f84b..5cba271 100755 --- a/tests/generators/generate-luks2-correct-full-json0.img.sh +++ b/tests/generators/generate-luks2-correct-full-json0.img.sh @@ -15,15 +15,6 @@ PATTERN="\"config\":{" KEY="\"config_key\":\"" -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() { read -r json_str < $TMPDIR/json0 @@ -47,41 +38,21 @@ function generate() printf $format_str $KEY $fill ${json_str:$offset} | _dd of=$TMPDIR/json0 bs=1 seek=$offset conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 #json_str_res0=$(< $TMPDIR/json_res0) read -r json_str_res0 < $TMPDIR/json_res0 test ${#json_str_res0} -eq $((LUKS2_JSON_SIZE*512-1)) || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh b/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh index 3d4f729..1365e0c 100755 --- a/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh +++ b/tests/generators/generate-luks2-corrupted-hdr0-with-correct-chks.img.sh @@ -11,14 +11,6 @@ # $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 -} - function generate() { read -r json_str < $TMPDIR/json0 @@ -32,34 +24,19 @@ function generate() printf "%s" $json_new_str | _dd of=$TMPDIR/json0 bs=512 count=$LUKS2_JSON_SIZE - 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 + lib_mangle_json_hdr0 } function check() { - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 + lib_hdr0_checksum || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 read -r json_str_res0 < $TMPDIR/json_res0 test ${#json_str_res0} -eq $((LUKS2_JSON_SIZE*512)) || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh b/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh index 026393c..fcbbb1e 100755 --- a/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh +++ b/tests/generators/generate-luks2-corrupted-hdr1-with-correct-chks.img.sh @@ -11,14 +11,6 @@ # $1 full target dir # $2 full source luks2 image -function prepare() -{ - cp $SRC_IMG $TGT_IMG - test -d $TMPDIR || mkdir $TMPDIR - read_luks2_json1 $TGT_IMG $TMPDIR/json1 - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 -} - function generate() { read -r json_str < $TMPDIR/json1 @@ -32,35 +24,19 @@ function generate() printf "%s" $json_new_str | _dd of=$TMPDIR/json1 bs=512 count=$LUKS2_JSON_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json1 $TMPDIR/area1 - erase_checksum $TMPDIR/area1 - chks1=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks1 $TMPDIR/area1 - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG + lib_mangle_json_hdr1 } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 - chks_res1=$(read_sha256_checksum $TMPDIR/hdr_res1) - test "$chks1" = "$chks_res1" || exit 2 + lib_hdr1_checksum || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 read -r json_str_res1 < $TMPDIR/json_res1 test ${#json_str_res1} -eq $((LUKS2_JSON_SIZE*512)) || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh b/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh index be98722..925763e 100755 --- a/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-both-hdrs.img.sh @@ -11,42 +11,22 @@ # $1 full target dir # $2 full source luks2 image -function prepare() -{ - cp $SRC_IMG $TGT_IMG - test -d $TMPDIR || mkdir $TMPDIR - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 -} - function generate() { - chks0=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) - chks1=$(echo "D'oh!: arbitrary chosen string" | calc_sha256_checksum_stdin) - write_checksum $chks0 $TGT_IMG - write_checksum $chks1 $TMPDIR/hdr1 + CHKS0=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) + CHKS1=$(echo "D'oh!: arbitrary chosen string" | calc_sha256_checksum_stdin) + write_checksum $CHKS0 $TGT_IMG + write_checksum $CHKS1 $TMPDIR/hdr1 write_luks2_bin_hdr1 $TMPDIR/hdr1 $TGT_IMG } function check() { - chks_res0=$(read_sha256_checksum $TGT_IMG) - chks_res1=$(read_sha256_checksum $TMPDIR/hdr1) - test "$chks0" = "$chks_res0" || exit 2 - test "$chks1" = "$chks_res1" || exit 2 -} - -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 } -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh b/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh index ac75ccb..ae8c595 100755 --- a/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-hdr0.img.sh @@ -11,33 +11,18 @@ # 1 full target dir # 2 full source luks2 image -function prepare() -{ - cp $SRC_IMG $TGT_IMG -} - function generate() { - chks=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) - write_checksum $chks $TGT_IMG + CHKS0=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) + write_checksum $CHKS0 $TGT_IMG } function check() { - chks_res=$(read_sha256_checksum $TGT_IMG) - test "$chks" = "$chks_res" || exit 2 + lib_hdr0_checksum || exit 2 } -#function cleanup() -#{ -#} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -#cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh b/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh index f0ca01a..a56695d 100755 --- a/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh +++ b/tests/generators/generate-luks2-invalid-checksum-hdr1.img.sh @@ -11,38 +11,19 @@ # $1 full target dir # $2 full source luks2 image -function prepare() -{ - cp $SRC_IMG $TGT_IMG - test -d $TMPDIR || mkdir $TMPDIR - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 -} - function generate() { - chks=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) - write_checksum $chks $TMPDIR/hdr1 + CHKS1=$(echo "Arbitrary chosen string: D'oh!" | calc_sha256_checksum_stdin) + write_checksum $CHKS1 $TMPDIR/hdr1 write_luks2_bin_hdr1 $TMPDIR/hdr1 $TGT_IMG } function check() { - chks_res=$(read_sha256_checksum $TMPDIR/hdr1) - test "$chks" = "$chks_res" || exit 2 -} - -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR + lib_hdr1_checksum || exit 2 } -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-json-size-c0.img.sh b/tests/generators/generate-luks2-invalid-json-size-c0.img.sh index 2866b0b..13dea92 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c0.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c0.img.sh @@ -13,15 +13,6 @@ # $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() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512+4096)) @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c --arg js $JS 'if .config.json_size != ($js | tostring ) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-json-size-c1.img.sh b/tests/generators/generate-luks2-invalid-json-size-c1.img.sh index dcab9bc..5cdc7ce 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c1.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c1.img.sh @@ -13,15 +13,6 @@ # $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() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512-4096)) @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c --arg js $JS 'if .config.json_size != ($js | tostring ) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-json-size-c2.img.sh b/tests/generators/generate-luks2-invalid-json-size-c2.img.sh index 6de411a..4122338 100755 --- a/tests/generators/generate-luks2-invalid-json-size-c2.img.sh +++ b/tests/generators/generate-luks2-invalid-json-size-c2.img.sh @@ -14,15 +14,6 @@ # $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() { JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512)) @@ -33,24 +24,14 @@ function generate() json_str=$(jq -c '.' $TMPDIR/json0) write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() @@ -68,18 +49,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh index c4f002f..8187b72 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c0.img.sh @@ -14,15 +14,6 @@ # $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() { # make area 7 being included in area 6 @@ -34,38 +25,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c --arg off $OFFS 'if .config.keyslots_size != ( .segments."0".offset | tonumber - ($off | tonumber) + 4096 | tostring ) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh index eff2064..2ba1a9b 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c1.img.sh @@ -13,15 +13,6 @@ # $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() { json_str=$(jq -c '.config.keyslots_size = (.config.keyslots_size | tonumber - 1 | tostring)' $TMPDIR/json0) @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if (.config.keyslots_size | tonumber % 4096) == 0 then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh b/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh index f70f39f..f983438 100755 --- a/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh +++ b/tests/generators/generate-luks2-invalid-keyslots-size-c2.img.sh @@ -14,15 +14,6 @@ # $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() { json_str=$(jq '.config.keyslots_size = ([.keyslots[].area.size] | map(tonumber) | add - 4096 | tostring )' $TMPDIR/json0) @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .config.keyslots_size != ([.keyslots[].area.size ] | map(tonumber) | add - 4096 | tostring) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-object-type-json0.img.sh b/tests/generators/generate-luks2-invalid-object-type-json0.img.sh index 1063864..616120b 100755 --- a/tests/generators/generate-luks2-invalid-object-type-json0.img.sh +++ b/tests/generators/generate-luks2-invalid-object-type-json0.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str < $TMPDIR/json0 @@ -31,40 +22,20 @@ function generate() printf "%s" "$json_str" | _dd of=$TMPDIR/json0 bs=1 conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 read -r json_str_res0 < $TMPDIR/json_res0 test "$json_str" = "$json_str_res0" || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh b/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh index 996d997..3f34692 100755 --- a/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh +++ b/tests/generators/generate-luks2-invalid-opening-char-json0.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str < $TMPDIR/json0 @@ -31,40 +22,20 @@ function generate() printf "%s" "$json_str" | _dd of=$TMPDIR/json0 bs=1 conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 IFS= read -r json_str_res0 < $TMPDIR/json_res0 test "$json_str" = "$json_str_res0" || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-tokens.img.sh b/tests/generators/generate-luks2-invalid-tokens.img.sh new file mode 100755 index 0000000..9719cf7 --- /dev/null +++ b/tests/generators/generate-luks2-invalid-tokens.img.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where keyslot is not of type object. +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c 'del(.tokens) | .tokens = 42' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if .tokens != 42 + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-invalid-top-objects.img.sh b/tests/generators/generate-luks2-invalid-top-objects.img.sh new file mode 100755 index 0000000..174dc2c --- /dev/null +++ b/tests/generators/generate-luks2-invalid-top-objects.img.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where multiple top objects are not of type object. +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c 'del(.tokens) | .tokens = 42 | + del(.digests) | .digests = 42 | + del(.keyslots) | .keyslots = [] | + del(.segments) | .segments = "hi"' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if (.tokens != 42) or (.digests != 42) or (.keyslots != []) or (.segments != "hi") + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-invalid-af.img.sh b/tests/generators/generate-luks2-keyslot-invalid-af.img.sh new file mode 100755 index 0000000..99f7679 --- /dev/null +++ b/tests/generators/generate-luks2-keyslot-invalid-af.img.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where keyslot AF type is invalid. +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c 'del(.keyslots."0".af.type) | .keyslots."0".af.type = 42' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if (.keyslots."0".af.type != 42) + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh b/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh new file mode 100755 index 0000000..723d58a --- /dev/null +++ b/tests/generators/generate-luks2-keyslot-invalid-area-size.img.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where keyslot area object size is UINT64_MAX and will overflow with added length +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c '.keyslots."0"."area".size = "18446744073709551615"' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if (.keyslots."0"."area".size != "18446744073709551615") + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-invalid-area.img.sh b/tests/generators/generate-luks2-keyslot-invalid-area.img.sh new file mode 100755 index 0000000..c41037e --- /dev/null +++ b/tests/generators/generate-luks2-keyslot-invalid-area.img.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where keyslot area object is not of type object. +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c 'del(.keyslots."0".area) | .keyslots."0".area = 42' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if (.keyslots."0".area != 42) + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh b/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh new file mode 100755 index 0000000..5fcfef2 --- /dev/null +++ b/tests/generators/generate-luks2-keyslot-invalid-objects.img.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate header with well-formed json format +# where multiple keyslots objects are not of type object. +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + json_str=$(jq -c 'del(.keyslots."0".kdf) | .keyslots."0".kdf = 42 | + del(.keyslots."0".af) | .keyslots."0".af = 42' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + write_luks2_json "$json_str" $TMPDIR/json1 + + lib_mangle_json_hdr0 + lib_mangle_json_hdr1 +} + +function check() +{ + lib_hdr0_checksum || exit 2 + lib_hdr1_checksum || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if (.keyslots."0".kdf != 42) or (.keyslots."0".af != 42) + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-missing-digest.img.sh b/tests/generators/generate-luks2-keyslot-missing-digest.img.sh index 1914581..49aeff1 100755 --- a/tests/generators/generate-luks2-keyslot-missing-digest.img.sh +++ b/tests/generators/generate-luks2-keyslot-missing-digest.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str_orig < $TMPDIR/json0 @@ -33,40 +24,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_arr_len=$(jq -c -M '.digests."0".keyslots | length' $TMPDIR/json_res0) test $((arr_len-1)) -eq $new_arr_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh b/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh index 5e1d6ef..5ba55f1 100755 --- a/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh +++ b/tests/generators/generate-luks2-keyslot-too-many-digests.img.sh @@ -14,15 +14,6 @@ # $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() { # add keyslot 1 to second digest @@ -31,40 +22,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_arr_len=$(jq -c -M '.digests."1".keyslots | length' $TMPDIR/json_res0) test 1 -eq $new_arr_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh index ca6b0c8..2a44678 100755 --- a/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 128 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-128k.img.sh b/tests/generators/generate-luks2-metadata-size-128k.img.sh index fe76598..79cccbd 100755 --- a/tests/generators/generate-luks2-metadata-size-128k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-128k.img.sh @@ -15,15 +15,6 @@ # $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() { # 128KiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh index 14a6613..f0e6e8d 100755 --- a/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 16 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh index fdcd715..25c19c1 100755 --- a/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 1 MiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-1m.img.sh b/tests/generators/generate-luks2-metadata-size-1m.img.sh index 25722dd..9228fe5 100755 --- a/tests/generators/generate-luks2-metadata-size-1m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-1m.img.sh @@ -15,15 +15,6 @@ # $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() { # 1 MiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh index 0ed66e1..b4c1027 100755 --- a/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 256 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-256k.img.sh b/tests/generators/generate-luks2-metadata-size-256k.img.sh index aa5df05..60ec878 100755 --- a/tests/generators/generate-luks2-metadata-size-256k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-256k.img.sh @@ -15,14 +15,6 @@ # $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() { @@ -44,32 +36,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +56,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh index 4773c94..0c68905 100755 --- a/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh @@ -15,15 +15,6 @@ # $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() { # 2 MiB metadata @@ -44,34 +35,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -79,18 +57,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-2m.img.sh b/tests/generators/generate-luks2-metadata-size-2m.img.sh index ae9bc30..0dbb521 100755 --- a/tests/generators/generate-luks2-metadata-size-2m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-2m.img.sh @@ -15,15 +15,6 @@ # $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() { # 2 MiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh index af18f43..effd244 100755 --- a/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 32 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-32k.img.sh b/tests/generators/generate-luks2-metadata-size-32k.img.sh index 40c921e..f970144 100755 --- a/tests/generators/generate-luks2-metadata-size-32k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-32k.img.sh @@ -15,15 +15,6 @@ # $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() { # 32KiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh index 332d67e..f423850 100755 --- a/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh @@ -15,15 +15,6 @@ # $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() { # 4 MiB metadata @@ -44,34 +35,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -79,18 +57,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-4m.img.sh b/tests/generators/generate-luks2-metadata-size-4m.img.sh index 21715fb..b15ad4b 100755 --- a/tests/generators/generate-luks2-metadata-size-4m.img.sh +++ b/tests/generators/generate-luks2-metadata-size-4m.img.sh @@ -15,15 +15,6 @@ # $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() { # 4 MiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh index 581dea0..4980816 100755 --- a/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 512 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-512k.img.sh b/tests/generators/generate-luks2-metadata-size-512k.img.sh index 8b196e6..f3da37f 100755 --- a/tests/generators/generate-luks2-metadata-size-512k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-512k.img.sh @@ -15,15 +15,6 @@ # $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() { # 512KiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh index 16e2078..3913f03 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh @@ -14,15 +14,6 @@ # $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() { # 64KiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh index 7ff670b..b01f933 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh @@ -14,15 +14,6 @@ # $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() { # 64KiB metadata @@ -45,32 +36,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE # .keyslots.7.area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots.7.area.size | tonumber) + 1) | tostring ) | jq -c --arg mda $((2*TEST_MDA_SIZE_BYTES)) --arg jsize $JSON_SIZE \ @@ -79,18 +57,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh b/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh index 8f3d8d7..5b8517a 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh @@ -14,15 +14,6 @@ # $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() { # 64KiB metadata @@ -45,32 +36,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE --arg off $DATA_OFFSET --arg mda $((2*TEST_MDA_SIZE_BYTES)) \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -79,18 +57,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh index 1b246cc..9635ab7 100755 --- a/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh @@ -16,15 +16,6 @@ # $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() { # 64 KiB metadata @@ -45,34 +36,21 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area0 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE } function check() { - read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE - local str_res0=$(head -c 6 $TMPDIR/hdr_res0) - test "$str_res0" = "VACUUM" || exit 2 + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -80,18 +58,7 @@ function check() then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-64k.img.sh b/tests/generators/generate-luks2-metadata-size-64k.img.sh index 4e320f2..50941b8 100755 --- a/tests/generators/generate-luks2-metadata-size-64k.img.sh +++ b/tests/generators/generate-luks2-metadata-size-64k.img.sh @@ -15,15 +15,6 @@ # $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() { # 64KiB metadata @@ -44,32 +35,19 @@ function generate() test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES - merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE - merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE - - erase_checksum $TMPDIR/area0 - chks0=$(calc_sha256_checksum_file $TMPDIR/area0) - write_checksum $chks0 $TMPDIR/area0 - - erase_checksum $TMPDIR/area1 - chks0=$(calc_sha256_checksum_file $TMPDIR/area1) - write_checksum $chks0 $TMPDIR/area1 - - kill_bin_hdr $TMPDIR/area1 - - write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE - write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill } function check() { - read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE - local str_res1=$(head -c 6 $TMPDIR/hdr_res1) - test "$str_res1" = "VACUUM" || exit 2 + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or @@ -77,18 +55,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh new file mode 100755 index 0000000..d2ddd61 --- /dev/null +++ b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate primary with predefined json_size. There's only limited +# set of values allowed as json size in config section of LUKS2 +# metadata +# +# secondary header is corrupted on purpose as well +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M + + TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512)) + TEST_MDA_SIZE_BOGUS_BYTES=$((TEST_MDA_SIZE*512*2*1024)) + TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE)) + KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024)) + JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024)) + JSON_SIZE=$((TEST_JSN_SIZE*512)) + DATA_OFFSET=16777216 + + json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \ + '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) | + .config.json_size = $jsize | + .segments."0".offset = $off' $TMPDIR/json0) + test -n "$json_str" || exit 2 + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE + + write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES + write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BOGUS_BYTES + + write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES + + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE kill + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE +} + +function check() +{ + lib_hdr0_killed $TEST_MDA_SIZE || exit 2 + + read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE + jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ + 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or + (.config.json_size != $jsize) + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-metadata-size-invalid.img.sh b/tests/generators/generate-luks2-metadata-size-invalid.img.sh new file mode 100755 index 0000000..745fc5c --- /dev/null +++ b/tests/generators/generate-luks2-metadata-size-invalid.img.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate primary with predefined json_size. There's only limited +# set of values allowed as json size in config section of LUKS2 +# metadata +# +# secondary header is corrupted on purpose as well +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M + + TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512)) + TEST_MDA_SIZE_BOGUS_BYTES=$((TEST_MDA_SIZE*512*2*1024)) + TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE)) + KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024)) + JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024)) + JSON_SIZE=$((TEST_JSN_SIZE*512)) + DATA_OFFSET=16777216 + + json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \ + '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) | + .config.json_size = $jsize | + .segments."0".offset = $off' $TMPDIR/json0) + test -n "$json_str" || exit 2 + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE + write_luks2_json "$json_str" $TMPDIR/json1 $TEST_JSN_SIZE + + write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BOGUS_BYTES + write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BOGUS_BYTES + + lib_mangle_json_hdr0 $TEST_MDA_SIZE $TEST_JSN_SIZE + lib_mangle_json_hdr1 $TEST_MDA_SIZE $TEST_JSN_SIZE kill +} + +function check() +{ + lib_hdr1_killed $TEST_MDA_SIZE || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE + jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \ + 'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or + (.config.json_size != $jsize) + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh b/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh index d6ebe3d..a0ca53c 100755 --- a/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh +++ b/tests/generators/generate-luks2-missing-keyslot-referenced-in-digest.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str_orig < $TMPDIR/json0 @@ -35,40 +26,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_arr_len=$(jq -c -M '.digests."0".keyslots | length' $TMPDIR/json_res0) test $((arr_len+1)) -eq $new_arr_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh b/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh index 85798e5..84d7ed2 100755 --- a/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh +++ b/tests/generators/generate-luks2-missing-keyslot-referenced-in-token.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str_orig < $TMPDIR/json0 @@ -33,40 +24,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_arr_len=$(jq -c -M '.tokens."0".keyslots | length' $TMPDIR/json_res0) test $new_arr_len -eq 2 || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh b/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh index 333462b..300c2dc 100755 --- a/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh +++ b/tests/generators/generate-luks2-missing-segment-referenced-in-digest.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str_orig < $TMPDIR/json0 @@ -35,40 +26,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_arr_len=$(jq -c -M '.digests."0".segments | length' $TMPDIR/json_res0) test $((arr_len+1)) -eq $new_arr_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh b/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh index 916cff7..9c5ed0b 100755 --- a/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh +++ b/tests/generators/generate-luks2-missing-trailing-null-byte-json0.img.sh @@ -17,15 +17,6 @@ PATTERN="\"config\":{" KEY="\"config_key\":\"" -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() { read -r json_str < $TMPDIR/json0 @@ -50,40 +41,20 @@ function generate() printf $format_str $KEY $fill ${json_str:$offset} | _dd of=$TMPDIR/json0 bs=1 seek=$offset conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 read -r json_str_res0 < $TMPDIR/json_res0 test ${#json_str_res0} -eq $((LUKS2_JSON_SIZE*512)) || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh b/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh index fbd8cd6..6f4aa7d 100755 --- a/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh +++ b/tests/generators/generate-luks2-non-null-byte-beyond-json0.img.sh @@ -14,15 +14,6 @@ # $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() { read -r json_str < $TMPDIR/json0 @@ -31,42 +22,22 @@ function generate() printf '%s' $json_str | _dd of=$TMPDIR/json0 bs=1 conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 read -r json_str_res0 < $TMPDIR/json_res0 local len=${#json_str_res0} len=$((len-1)) test ${json_str_res0:len:1} = "X" || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh b/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh index 7d46628..18abf23 100755 --- a/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh +++ b/tests/generators/generate-luks2-non-null-bytes-beyond-json0.img.sh @@ -17,15 +17,6 @@ QUOTE="[Homer J. Simpson]: Keep looking shocked and move slowly towards the cake." SPACE=20 -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() { read -r json_str < $TMPDIR/json0 @@ -35,42 +26,22 @@ function generate() printf '%s' "$QUOTE" | _dd of=$TMPDIR/json0 seek=$((json_len_orig+SPACE)) bs=1 conv=notrunc - 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 _dd if=$TMPDIR/json_res0 of=$TMPDIR/quote skip=$((json_len_orig+SPACE)) count=${#QUOTE} bs=1 json_str_res0=$(head -c ${#QUOTE} $TMPDIR/quote) test "$json_str_res0" = "$QUOTE" || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh index c319ca3..23883bb 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c0-json0.img.sh @@ -13,15 +13,6 @@ # $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() { # copy area 6 offset and length into area 7 @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if (.keyslots."6".area.offset != .keyslots."7".area.offset) or (.keyslots."6".area.size != .keyslots."7".area.size) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh index 39f0c6a..0733627 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c1-json0.img.sh @@ -13,15 +13,6 @@ # $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() { # make area 7 being included in area 6 @@ -31,20 +22,12 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if (.keyslots."7".area.offset != (.keyslots."6".area.offset | tonumber + 1 | tostring)) or @@ -53,18 +36,7 @@ function check() then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh b/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh index 4c02008..6699b38 100755 --- a/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh +++ b/tests/generators/generate-luks2-overlapping-areas-c2-json0.img.sh @@ -13,15 +13,6 @@ # $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() { # make area 7 being included in area 6 @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .keyslots."7".area.offset != ([.keyslots."6".area.offset, .keyslots."6".area.size ] | map(tonumber) | add - 1 | tostring) then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh b/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh index 1517ed6..e035f94 100755 --- a/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh +++ b/tests/generators/generate-luks2-pbkdf2-leftover-params-0.img.sh @@ -14,15 +14,6 @@ # $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() { # add keyslot 1 to second digest @@ -32,40 +23,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_obj_len=$(jq -c -M '.keyslots."2".kdf | length' $TMPDIR/json_res0) test $((obj_len+2)) -eq $new_obj_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh b/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh index c6aa5bf..d82c2bd 100755 --- a/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh +++ b/tests/generators/generate-luks2-pbkdf2-leftover-params-1.img.sh @@ -14,15 +14,6 @@ # $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() { # add keyslot 1 to second digest @@ -32,40 +23,20 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 + lib_hdr0_checksum || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 - chks_res0=$(read_sha256_checksum $TGT_IMG) - test "$chks0" = "$chks_res0" || exit 2 new_obj_len=$(jq -c -M '.keyslots."2".kdf | length' $TMPDIR/json_res0) test $((obj_len+2)) -eq $new_obj_len || exit 2 } -function cleanup() -{ - rm -f $TMPDIR/* - rm -fd $TMPDIR -} - -test $# -eq 2 || exit 1 - -TGT_IMG=$1/$(test_img_name $0) -SRC_IMG=$2 - -prepare +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh new file mode 100755 index 0000000..ca17aac --- /dev/null +++ b/tests/generators/generate-luks2-segment-crypt-empty-encryption.img.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +. lib.sh + +# +# *** Description *** +# +# generate primary header with segment empty encryption field +# +# secondary header is corrupted on purpose as well +# + +# $1 full target dir +# $2 full source luks2 image + +function generate() +{ + # remove mandatory encryption field + json_str=$(jq -c '.segments."0".encryption = ""' $TMPDIR/json0) + test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2 + + write_luks2_json "$json_str" $TMPDIR/json0 + + lib_mangle_json_hdr0_kill_hdr1 +} + +function check() +{ + lib_hdr1_killed || exit 2 + + read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 + jq -c 'if .segments."0".encryption != "" + then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5 +} + +lib_prepare $@ +generate +check +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh index bcd648a..e92bc2a 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".encryption then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh index e64feef..77beb53 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".iv_tweak then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh b/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh index de757db..0609533 100755 --- a/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".sector_size then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh index 59c7345..9d7e584 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".encryption | type != "object" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh index ca9461e..0830a16 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".iv_tweak != "dynamic" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh index 4ca05eb..069b6c0 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".sector_size != 1023 then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh index f8d251c..c310ff1 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".sector_size != "4096" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh index 87566ec..b4b8b39 100755 --- a/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh +++ b/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".sector_size != -1024 then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-missing-offset.img.sh b/tests/generators/generate-luks2-segment-missing-offset.img.sh index 6652288..6d5811e 100755 --- a/tests/generators/generate-luks2-segment-missing-offset.img.sh +++ b/tests/generators/generate-luks2-segment-missing-offset.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".offset then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-missing-size.img.sh b/tests/generators/generate-luks2-segment-missing-size.img.sh index 616d8b3..579858f 100755 --- a/tests/generators/generate-luks2-segment-missing-size.img.sh +++ b/tests/generators/generate-luks2-segment-missing-size.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-missing-type.img.sh b/tests/generators/generate-luks2-segment-missing-type.img.sh index d0014a2..5b74c5d 100755 --- a/tests/generators/generate-luks2-segment-missing-type.img.sh +++ b/tests/generators/generate-luks2-segment-missing-type.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".type then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-two.img.sh b/tests/generators/generate-luks2-segment-two.img.sh index 743bbbb..798c5be 100755 --- a/tests/generators/generate-luks2-segment-two.img.sh +++ b/tests/generators/generate-luks2-segment-two.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."1" | type != "object" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-unknown-type.img.sh b/tests/generators/generate-luks2-segment-unknown-type.img.sh index a6ef8ad..814344a 100755 --- a/tests/generators/generate-luks2-segment-unknown-type.img.sh +++ b/tests/generators/generate-luks2-segment-unknown-type.img.sh @@ -14,15 +14,6 @@ # $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() { # remove mandatory encryption field @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".type != "some_type" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup 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 index 2499a5e..3ba9d47 100755 --- a/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-0.img.sh @@ -13,15 +13,6 @@ # $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) @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || 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 +lib_prepare $@ generate check -cleanup +lib_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 index 702fe71..11a94d7 100755 --- a/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-backup-key-1.img.sh @@ -13,15 +13,6 @@ # $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) @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh b/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh index 5359954..72da1f1 100755 --- a/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".flags != [ "hello", 1 ] then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-flags.img.sh b/tests/generators/generate-luks2-segment-wrong-flags.img.sh index 3ceddbf..19d6340 100755 --- a/tests/generators/generate-luks2-segment-wrong-flags.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-flags.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".flags != "hello" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-offset.img.sh b/tests/generators/generate-luks2-segment-wrong-offset.img.sh index 9efc756..c9b1b50 100755 --- a/tests/generators/generate-luks2-segment-wrong-offset.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-offset.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".offset != "-42" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-size-0.img.sh b/tests/generators/generate-luks2-segment-wrong-size-0.img.sh index 58b12ef..b9227a7 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-0.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-0.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != 4096 then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-size-1.img.sh b/tests/generators/generate-luks2-segment-wrong-size-1.img.sh index 8171445..6be5031 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-1.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-1.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != "automatic" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-size-2.img.sh b/tests/generators/generate-luks2-segment-wrong-size-2.img.sh index f694cf7..311c0e8 100755 --- a/tests/generators/generate-luks2-segment-wrong-size-2.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-size-2.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != "511" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-segment-wrong-type.img.sh b/tests/generators/generate-luks2-segment-wrong-type.img.sh index 4f7fd64..c041157 100755 --- a/tests/generators/generate-luks2-segment-wrong-type.img.sh +++ b/tests/generators/generate-luks2-segment-wrong-type.img.sh @@ -13,15 +13,6 @@ # $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() { # remove mandatory encryption field @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".type != 42 then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-uint64-max-segment-size.img.sh b/tests/generators/generate-luks2-uint64-max-segment-size.img.sh index 27d7fd2..f966e1d 100755 --- a/tests/generators/generate-luks2-uint64-max-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-max-segment-size.img.sh @@ -14,15 +14,6 @@ # $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() { # UINT64_MAX - 511 (so that it's sector aligned) @@ -31,38 +22,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != "18446744073709551104" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh b/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh index 01657d6..4e064e4 100755 --- a/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-overflow-segment-size.img.sh @@ -13,15 +13,6 @@ # $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() { json_str=$(jq -c '.segments."0".size = "18446744073709551616"' $TMPDIR/json0) @@ -29,38 +20,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != "18446744073709551616" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh b/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh index 0a45a05..6687f35 100755 --- a/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh +++ b/tests/generators/generate-luks2-uint64-signed-segment-size.img.sh @@ -13,15 +13,6 @@ # $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() { # UINT64_MAX + 1 (it's 512 sector aligned) @@ -30,38 +21,19 @@ function generate() 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 + lib_mangle_json_hdr0_kill_hdr1 } 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 + lib_hdr1_killed || exit 2 read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 jq -c 'if .segments."0".size != "-512" then error("Unexpected value in result json") 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 +lib_prepare $@ generate check -cleanup +lib_cleanup diff --git a/tests/generators/lib.sh b/tests/generators/lib.sh index 9686148..c0e9cc1 100644 --- a/tests/generators/lib.sh +++ b/tests/generators/lib.sh @@ -20,6 +20,10 @@ LUKS2_BIN_HDR_CHKS_LENGTH=64 [ -z "$srcdir" ] && srcdir="." TMPDIR=$srcdir/tmp +# to be set by individual generator +TGT_IMG="" +SRC_IMG="" + repeat_str() { printf "$1"'%.0s' $(eval "echo {1.."$(($2))"}"); } @@ -172,9 +176,108 @@ function _dd() } function write_bin_hdr_size() { - printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=1 conv=notrunc + printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=1 conv=notrunc } function write_bin_hdr_offset() { - printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=32 conv=notrunc + printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=32 conv=notrunc +} + +# generic header helpers +# $TMPDIR/json0 - JSON hdr1 +# $TMPDIR/json1 - JSON hdr2 +# $TMPDIR/hdr0 - bin hdr1 +# $TMPDIR/hdr1 - bin hdr2 + +# 1:target_dir 2:source_image +function lib_prepare() +{ + test $# -eq 2 || exit 1 + + TGT_IMG=$1/$(test_img_name $0) + SRC_IMG=$2 + + # wipe checksums + CHKS0=0 + CHKS1=0 + + cp $SRC_IMG $TGT_IMG + test -d $TMPDIR || mkdir $TMPDIR + read_luks2_json0 $TGT_IMG $TMPDIR/json0 + read_luks2_json1 $TGT_IMG $TMPDIR/json1 + read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0 + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1 +} + +function lib_cleanup() +{ + rm -f $TMPDIR/* + rm -fd $TMPDIR +} + +function lib_mangle_json_hdr0() +{ + local mda_sz=${1:-} + local jsn_sz=${2:-} + local kill_hdr=${3:-} + + merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $jsn_sz + erase_checksum $TMPDIR/area0 + CHKS0=$(calc_sha256_checksum_file $TMPDIR/area0) + write_checksum $CHKS0 $TMPDIR/area0 + test -n "$kill_hdr" && kill_bin_hdr $TMPDIR/area0 + write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $mda_sz +} + +function lib_mangle_json_hdr1() +{ + local mda_sz=${1:-} + local jsn_sz=${2:-} + local kill_hdr=${3:-} + + merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json1 $TMPDIR/area1 $jsn_sz + erase_checksum $TMPDIR/area1 + CHKS1=$(calc_sha256_checksum_file $TMPDIR/area1) + write_checksum $CHKS1 $TMPDIR/area1 + test -n "$kill_hdr" && kill_bin_hdr $TMPDIR/area1 + write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $mda_sz +} + +function lib_mangle_json_hdr0_kill_hdr1() +{ + lib_mangle_json_hdr0 + + kill_bin_hdr $TMPDIR/hdr1 + write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG +} + +function lib_hdr0_killed() +{ + local mda_sz=${1:-} + + read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $mda_sz + local str_res0=$(head -c 6 $TMPDIR/hdr_res0) + test "$str_res0" = "VACUUM" +} + +function lib_hdr1_killed() +{ + local mda_sz=${1:-} + + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $mda_sz + local str_res1=$(head -c 6 $TMPDIR/hdr_res1) + test "$str_res1" = "VACUUM" +} + +function lib_hdr0_checksum() +{ + local chks_res0=$(read_sha256_checksum $TGT_IMG) + test "$CHKS0" = "$chks_res0" +} + +function lib_hdr1_checksum() +{ + read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 + local chks_res1=$(read_sha256_checksum $TMPDIR/hdr_res1) + test "$CHKS1" = "$chks_res1" } diff --git a/tests/integrity-compat-test b/tests/integrity-compat-test index a3d3b8c..208eafb 100755 --- a/tests/integrity-compat-test +++ b/tests/integrity-compat-test @@ -9,7 +9,7 @@ INTSETUP_VALGRIND=../.libs/integritysetup INTSETUP_LIB_VALGRIND=../.libs DEV_NAME=dmc_test -DEV_NAME_BIG=dmc_fake +DEV_NAME2=dmc_fake DEV_LOOP="" DEV=test123.img DEV2=test124.img @@ -23,7 +23,7 @@ dmremove() { # device cleanup() { [ -b /dev/mapper/$DEV_NAME ] && dmremove $DEV_NAME - [ -b /dev/mapper/$DEV_NAME_BIG ] && dmremove $DEV_NAME_BIG + [ -b /dev/mapper/$DEV_NAME2 ] && dmremove $DEV_NAME2 [ -n "$DEV_LOOP" ] && losetup -d "$DEV_LOOP" DEV_LOOP="" rm -f $DEV $DEV2 $KEY_FILE $KEY_FILE2 >/dev/null 2>&1 @@ -61,9 +61,15 @@ function dm_integrity_features() [ $VER_MIN -gt 2 ] && { DM_INTEGRITY_BITMAP=1 } + [ $VER_MIN -gt 5 ] && { + DM_INTEGRITY_RESIZE_SUPPORTED=1 + } [ $VER_MIN -gt 6 ] && { DM_INTEGRITY_HMAC_FIX=1 } + [ $VER_MIN -gt 7 ] && { + DM_INTEGRITY_RESET=1 + } } add_device() { @@ -107,14 +113,14 @@ kernel_param_check() # number value function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." - [ ! -f $INTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." - export LD_LIBRARY_PATH="$INTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $INTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$INTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } function valgrind_run() { - INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${INTSETUP_VALGRIND} "$@" + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${INTSETUP_VALGRIND} "$@" } int_check_sum_only() # checksum @@ -165,12 +171,11 @@ intformat() # alg alg_out tagsize outtagsize sector_size csum [keyfile keysize] echo -n "[FORMAT]" $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 + if [[ $1 =~ "sha2" || $1 =~ "crc" ]] ; then + fail "Cannot format device." fi - fail "Cannot format device." + echo "[N/A]" + return fi dump_check "tag_size" $4 @@ -212,7 +217,14 @@ int_error_detection() # mode alg tagsize outtagsize sector_size key_file key_siz echo -n "[INTEGRITY:$1:$2:$4:$5]" echo -n "[FORMAT]" - $INTSETUP format -q --integrity $2 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV $INT_MODE >/dev/null || fail "Cannot format device." + $INTSETUP format -q --integrity $2 $TAG_PARAMS --sector-size $5 $KEY_PARAMS $DEV $INT_MODE >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + if [[ $2 =~ "sha2" || $2 =~ "crc" ]] ; then + fail "Cannot format device." + fi + echo "[N/A]" + return + fi echo -n "[ACTIVATE]" $INTSETUP open $DEV $DEV_NAME --integrity $2 --integrity-no-journal $KEY_PARAMS $INT_MODE || fail "Cannot activate device." @@ -245,27 +257,27 @@ 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:$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." + 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." - echo -n "[ACTIVATE]" + echo -n "[ACTIVATE]" - $INTSETUP open $DEV $DEV_NAME $ARGS || fail "Cannot activate device." + $INTSETUP open $DEV $DEV_NAME $ARGS || fail "Cannot activate device." - echo -n "[KEYED HASH]" - 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." + echo -n "[KEYED HASH]" + 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." - status_check "journal watermark" "${4}%" - status_check "journal commit time" "${5} ms" - status_check "journal integrity MAC" $9 + status_check "journal watermark" "${4}%" + status_check "journal commit time" "${5} ms" + status_check "journal integrity MAC" $9 - echo -n "[REMOVE]" - $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." - echo "[OK]" + echo -n "[REMOVE]" + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + echo "[OK]" } @@ -326,12 +338,91 @@ int_mode() # alg tag_size sector_size [keyfile keysize] echo "[OK]" } +check_device_size() # device_name expected_size error_message +{ + CURRENT_SIZE=$(dmsetup table | grep $1 | cut -d' ' -f 3) + [ $CURRENT_SIZE -eq $2 ] || fail "$3: expected $1 to be of size $2, but is $CURRENT_SIZE" +} + +test_resize() # description detached_metadata wipe args +{ + echo -n "$1" + if [ -z "$DM_INTEGRITY_RESIZE_SUPPORTED" ] ; then + echo "[N/A]" + return + fi + + args="$4" + if [ $2 -ne 0 ] ; then + echo -n "[DETACHED]" + else + echo -n "[INTERLEAVE]" + fi + if [ $3 -ne 0 ] ; then + wipe_flag="--wipe" + echo -n "[WIPE]" + else + wipe_flag="" + echo -n "[RECALCULATE]" + fi + + add_device + if [ $2 -ne 0 ] ; then + echo -n "[FORMAT]" + $INTSETUP format -q $args $DEV2 --data-device $DEV >/dev/null 2>&1 || fail "Cannot format device." + echo -n "[ACTIVATE]" + $INTSETUP open -q $args $DEV2 $DEV_NAME --data-device $DEV >/dev/null 2>&1 || fail "Cannot activate device." + else + echo -n "[FORMAT]" + $INTSETUP format -q $args $DEV >/dev/null 2>&1 || fail "Cannot format device." + echo -n "[ACTIVATE]" + $INTSETUP open -q $args $DEV $DEV_NAME >/dev/null 2>&1 || fail "Cannot activate device." + fi + + if [ $2 -ne 0 ] ; then + # the whole device has 32MiB, if metadata is detached + WHOLE_DISK_SIZE=65536 + else + WHOLE_DISK_SIZE=$(dmsetup table | grep $DEV_NAME | cut -d' ' -f 3) + fi + + echo -n "[SHRINK]" + $INTSETUP resize -q $wipe_flag $DEV_NAME --device-size 1MiB || fail "Failed to resize the device to 1MiB." + dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after shrink." + check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" + + echo -n "[FILL]" + $INTSETUP resize -q $wipe_flag $DEV_NAME --device-size 0 || fail "Failed to resize the device to maximum size." + dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after resize to maximum size." + check_device_size $DEV_NAME $WHOLE_DISK_SIZE "Resizing disk to maximum size failed" + + echo -n "[EXPAND FIXED]" + fallocate $DEV --len 64M + $INTSETUP resize -q $wipe_flag $DEV_NAME --device-size 40MiB || fail "Failed to expand the device to a fixed size." + dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detected after expanding to a fixed size." + check_device_size $DEV_NAME $(( 40*1024*1024 / 512 )) "Resizing disk after expanding to a fixed size failed" + + echo -n "[FILL]" + $INTSETUP resize -q $wipe_flag $DEV_NAME --device-size 0 >/dev/null 2>&1 || fail "Failed to resize the device to maximum size after increasing image size." + dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Error detection failed after increasing image size." + CURRENT_SIZE=$(dmsetup table | grep $DEV_NAME | cut -d' ' -f 3) + [ $CURRENT_SIZE -ge $(( 40*1024*1024 / 512 )) ] || fail "Growing integrity device failed $CURRENT_SIZE is not greater than 40MB ($(( 40*1024*1024 / 512 )) blocks)." + if [ $2 -ne 0 ] ; then + [ $CURRENT_SIZE -eq 131072 ] || fail "Growing integrity device failed $CURRENT_SIZE is not equal to 64MB (131072 blocks)." + fi + + echo -n "[REMOVE]" + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + echo "[OK]" +} + [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$INTSETUP" ] && skip "Cannot find $INTSETUP, test skipped." -which blockdev >/dev/null || skip "Cannot find blockdev utility, test skipped." +command -v blockdev >/dev/null || skip "Cannot find blockdev utility, test skipped." [ -n "$VALG" ] && valgrind_setup && INTSETUP=valgrind_run -which hexdump >/dev/null 2>&1 || skip "WARNING: hexdump tool required." +command -v hexdump >/dev/null || skip "WARNING: hexdump tool required." +command -v xxd >/dev/null || skip "WARNING: xxd tool required." modprobe dm-integrity >/dev/null 2>&1 dm_integrity_features @@ -340,6 +431,7 @@ intformat blake2s-256 blake2s-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3 intformat blake2b-256 blake2b-256 32 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 intformat crc32c crc32c 0 4 512 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 intformat crc32 crc32 0 4 512 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 +intformat xxhash64 xxhash64 0 8 512 6ff6bb889a8485f1fb26aa82671ff5da64f60381fc469e31d7be6094241eee09 intformat sha1 sha1 0 20 512 6eedd6344dab8875cd185fcd6565dfc869ab36bc57e577f40c685290b1fa7fe7 intformat sha1 sha1 16 16 4096 e152ec88227b539cd9cafd8bdb587a1072d720cd6bcebe1398d4136c9e7f337b intformat sha256 sha256 0 32 512 8e5fe4119558e117bfc40e3b0f13ade3abe497b52604d4c7cca0cfd6c7f4cf11 @@ -349,17 +441,19 @@ intformat hmac-sha256 hmac\(sha256\) 0 32 4096 33f7dfa5163ca9f740383fb8b0919574 intformat hmac-sha256 hmac\(sha256\) 0 32 4096 33f7dfa5163ca9f740383fb8b0919574e38a7b20a94a4170fde4238196b7c4b4 $KEY_FILE 4096 echo "Error detection tests:" -int_error_detection J crc32c 0 4 512 -int_error_detection J crc32c 0 4 4096 -int_error_detection J crc32 0 4 512 -int_error_detection J crc32 0 4 4096 -int_error_detection J sha1 0 20 512 -int_error_detection J sha1 16 16 512 -int_error_detection J sha1 0 20 4096 -int_error_detection J sha256 0 32 512 -int_error_detection J sha256 0 32 4096 - -which xxd >/dev/null 2>&1 || skip "WARNING: xxd tool required." +int_error_detection J crc32c 0 4 512 +int_error_detection J crc32c 0 4 4096 +int_error_detection J crc32 0 4 512 +int_error_detection J crc32 0 4 4096 +int_error_detection J xxhash64 0 8 512 +int_error_detection J xxhash64 0 8 4096 +int_error_detection J sha1 0 20 512 +int_error_detection J sha1 16 16 512 +int_error_detection J sha1 0 20 4096 +int_error_detection J sha256 0 32 512 +int_error_detection J sha256 0 32 4096 + +command -v xxd >/dev/null || skip "WARNING: xxd tool required." int_error_detection J hmac-sha256 0 32 512 $KEY_FILE 32 int_error_detection J hmac-sha256 0 32 4096 $KEY_FILE 32 @@ -392,7 +486,16 @@ if [ -n "$DM_INTEGRITY_RECALC" ] ; then 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." - echo "[OK]" + echo -n "[OK]" + if [ -n "$DM_INTEGRITY_RESET" ] ; then + $INTSETUP open $DEV $DEV_NAME -I sha256 --integrity-recalculate-reset || fail "Cannot activate device." + dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=1M 2>/dev/null || fail "Cannot reset recalculate tags in-kernel" + int_check_sum_only 08f63eb27fb9ce2ce903b0a56429c68ce5e209253ba42154841ef045a53839d7 + $INTSETUP close $DEV_NAME || fail "Cannot deactivate device." + echo "[RESET OK]" + else + echo "[RESET N/A]" + fi else echo "[N/A]" fi @@ -434,14 +537,14 @@ echo -n "Big device:" add_device DEV_LOOP=$(losetup -f $DEV --show) if [ -n "$DEV_LOOP" ] ; then -dmsetup create $DEV_NAME_BIG <<EOF +dmsetup create $DEV_NAME2 <<EOF 0 16284 linear $DEV_LOOP 0 16284 80000000000 zero EOF - [ ! -b /dev/mapper/$DEV_NAME_BIG ] && fail - $INTSETUP format -q -s 512 --no-wipe /dev/mapper/$DEV_NAME_BIG - $INTSETUP open /dev/mapper/$DEV_NAME_BIG $DEV_NAME || fail - D_SIZE=$($INTSETUP dump /dev/mapper/$DEV_NAME_BIG | grep provided_data_sectors | sed -e 's/.*provided_data_sectors\ \+//g') + [ ! -b /dev/mapper/$DEV_NAME2 ] && fail + $INTSETUP format -q -s 512 --no-wipe /dev/mapper/$DEV_NAME2 + $INTSETUP open /dev/mapper/$DEV_NAME2 $DEV_NAME || fail + D_SIZE=$($INTSETUP dump /dev/mapper/$DEV_NAME2 | grep provided_data_sectors | sed -e 's/.*provided_data_sectors\ \+//g') A_SIZE=$(blockdev --getsz /dev/mapper/$DEV_NAME) # Compare strings (to avoid 64bit integers), not integers [ -n "$A_SIZE" -a "$D_SIZE" != "$A_SIZE" ] && fail @@ -450,6 +553,29 @@ else echo "[N/A]" fi +echo -n "Deferred removal of device:" +add_device +$INTSETUP format -q $DEV || fail "Cannot format device." +$INTSETUP open $DEV $DEV_NAME || fail "Cannot activate device." +dmsetup create $DEV_NAME2 --table "0 8 linear /dev/mapper/$DEV_NAME 0" +[ ! -b /dev/mapper/$DEV_NAME2 ] && fail +$INTSETUP close $DEV_NAME >/dev/null 2>&1 && fail +$INTSETUP -q status $DEV_NAME >/dev/null 2>&1 || fail +$INTSETUP close --deferred $DEV_NAME >/dev/null 2>&1 +if [ $? -eq 0 ] ; then + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail + $INTSETUP close --cancel-deferred $DEV_NAME >/dev/null 2>&1 + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" >/dev/null 2>&1 && fail + $INTSETUP close --deferred $DEV_NAME >/dev/null 2>&1 + dmsetup remove $DEV_NAME2 || fail + $INTSETUP -q status $DEV_NAME >/dev/null 2>&1 && fail + echo "[OK]" +else + dmsetup remove $DEV_NAME2 >/dev/null 2>&1 + $INTSETUP close $DEV_NAME >/dev/null 2>&1 + echo "[N/A]" +fi + echo -n "Fixed HMAC and legacy flags:" if [ -n "$DM_INTEGRITY_HMAC_FIX" ] ; then add_device @@ -481,4 +607,45 @@ else echo "[N/A]" fi +# shrinking the mapping should also work on older kernels +echo -n "[INTEGRITY BASIC RESIZE NOKEY]" +add_device +ARGS="--integrity crc32" + +echo -n "[FORMAT]" +$INTSETUP format -q $DEV $ARGS || fail "Cannot format device." +echo -n "[ACTIVATE]" +$INTSETUP open -q $DEV $DEV_NAME $ARGS >/dev/null 2>&1 || fail "Cannot activate device." +echo -n "[SHRINK]" +$INTSETUP resize $DEV_NAME --device-size 1MiB >/dev/null 2>&1 || fail "Failed to resize the device to 1MiB." +check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" +dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detectied after resize." +echo "[OK]" + +echo -n "[INTEGRITY BASIC RESIZE KEY]" +add_device + +ARGS="--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" + +echo -n "[FORMAT]" +$INTSETUP format -q $DEV $ARGS || fail "Cannot format device." +echo -n "[ACTIVATE]" +$INTSETUP open -q $DEV $DEV_NAME $ARGS >/dev/null 2>&1 || fail "Cannot activate device." +echo -n "[SHRINK]" +$INTSETUP resize $DEV_NAME --device-size 1MiB >/dev/null 2>&1 || fail "Failed to resize the device to 1MiB." +check_device_size $DEV_NAME $(( 1024*1024 / 512 )) "Shrinking device failed" +dd if=/dev/mapper/$DEV_NAME >/dev/null 2>&1 || fail "Errors detectied after resize." +echo "[OK]" + +test_resize "[INTEGRITY RESIZE NOKEY]" 0 0 "--integrity crc32" +test_resize "[INTEGRITY RESIZE NOKEY]" 0 1 "--integrity crc32" +test_resize "[INTEGRITY RESIZE NOKEY DETACHED]" 1 0 "--integrity crc32" +test_resize "[INTEGRITY RESIZE NOKEY DETACHED]" 1 1 "--integrity crc32" +if [ -n "$DM_INTEGRITY_HMAC_FIX" ] ; then + test_resize "[INTEGRITY RESIZE KEY]" 0 0 "--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" + test_resize "[INTEGRITY RESIZE KEY]" 0 1 "--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" + test_resize "[INTEGRITY RESIZE KEY DETACHED]" 1 0 "--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" + test_resize "[INTEGRITY RESIZE KEY DETACHED]" 1 1 "--integrity hmac-sha256 --integrity-key-size 128 --integrity-key-file $KEY_FILE --journal-integrity hmac-sha256 --journal-integrity-key-file $KEY_FILE --journal-integrity-key-size 128 --journal-crypt ctr-aes --journal-crypt-key-size 16 --journal-crypt-key-file $KEY_FILE" +fi + cleanup diff --git a/tests/keyring-compat-test b/tests/keyring-compat-test index 7a49936..ea88c21 100755 --- a/tests/keyring-compat-test +++ b/tests/keyring-compat-test @@ -21,12 +21,15 @@ NAME=testcryptdev CHKS_DMCRYPT=vk_in_dmcrypt.chk CHKS_KEYRING=vk_in_keyring.chk -PWD="aaa" +PWD="aaablabl" [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup -[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) function remove_mapping() { @@ -35,7 +38,7 @@ function remove_mapping() # unlink whole test keyring [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 rm -f $CHKS_DMCRYPT $CHKS_KEYRING } @@ -47,6 +50,18 @@ function skip() exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + function fail() { [ -n "$1" ] && echo "$1" @@ -92,11 +107,17 @@ function test_and_prepare_keyring() { function fips_mode() { - [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] + [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] } add_device() { - modprobe scsi_debug $@ delay=0 + rmmod scsi_debug >/dev/null 2>&1 + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 if [ $? -ne 0 ] ; then echo "This kernel seems to not support proper scsi_debug module, test skipped." exit 77 @@ -109,12 +130,14 @@ add_device() { [ -b $DEV ] || fail "Cannot find $DEV." } +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." -which dmsetup >/dev/null 2>&1 || skip "Cannot find dmsetup, test skipped" -which keyctl >/dev/null 2>&1 || skip "Cannot find keyctl, test skipped" -which xxd >/dev/null 2>&1 || skip "Cannot find xxd, test skipped" -which sha1sum > /dev/null 2>&1 || skip "Cannot find sha1sum, test skipped" -modprobe dm-crypt || fail "dm-crypt failed to load" +command -v dmsetup >/dev/null || skip "Cannot find dmsetup, test skipped" +command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped" +command -v xxd >/dev/null || skip "Cannot find xxd, test skipped" +command -v sha256sum >/dev/null || skip "Cannot find sha256sum, test skipped" +modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" dm_crypt_keyring_support || skip "dm-crypt doesn't support kernel keyring, test skipped." test_and_prepare_keyring @@ -126,23 +149,23 @@ dd if=/dev/urandom of=$DEV bs=1M count=$DEVSIZEMB oflag=direct > /dev/null 2>&1 #test aes cipher with xts mode, plain IV echo -n "Testing $CIPHER_XTS_PLAIN..." dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail load_key "$HEXKEY_32" logon $LOGON_KEY_32_OK "$TEST_KEYRING" || fail "Cannot load 32 byte logon key type" dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN :32:logon:$LOGON_KEY_32_OK 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)" # same test using message dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_XTS_PLAIN $HEXKEY_32 0 $DEV 0" || fail dmsetup suspend $NAME || fail dmsetup message $NAME 0 key wipe || fail dmsetup message $NAME 0 "key set :32:logon:$LOGON_KEY_32_OK" || fail dmsetup resume $NAME || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)" echo "OK" @@ -150,23 +173,23 @@ echo "OK" #test aes cipher, xts mode, essiv IV echo -n "Testing $CIPHER_CBC_ESSIV..." dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail load_key "$HEXKEY_16" logon $LOGON_KEY_16_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type" dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV :16:logon:$LOGON_KEY_16_OK 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)" # same test using message dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_ESSIV $HEXKEY_16 0 $DEV 0" || fail dmsetup suspend $NAME || fail dmsetup message $NAME 0 key wipe || fail dmsetup message $NAME 0 "key set :16:logon:$LOGON_KEY_16_OK" || fail dmsetup resume $NAME || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)" echo "OK" @@ -175,23 +198,23 @@ echo "OK" fips_mode || { echo -n "Testing $CIPHER_CBC_TCW..." dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail load_key "$HEXKEY_64" logon $LOGON_KEY_64_OK "$TEST_KEYRING" || fail "Cannot load 16 byte logon key type" dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW :64:logon:$LOGON_KEY_64_OK 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)" # same test using message dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail -sha1sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail +sha256sum /dev/mapper/$NAME > $CHKS_DMCRYPT || fail dmsetup remove --retry $NAME || fail dmsetup create $NAME --table "0 $DEVSECTORS crypt $CIPHER_CBC_TCW $HEXKEY_64 0 $DEV 0" || fail dmsetup suspend $NAME || fail dmsetup message $NAME 0 key wipe || fail dmsetup message $NAME 0 "key set :64:logon:$LOGON_KEY_64_OK" || fail dmsetup resume $NAME || fail -sha1sum /dev/mapper/$NAME > $CHKS_KEYRING || fail +sha256sum /dev/mapper/$NAME > $CHKS_KEYRING || fail dmsetup remove --retry $NAME || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksums mismatch (corruption)" echo "OK" @@ -201,10 +224,10 @@ echo -n "Test LUKS2 key refresh..." echo $PWD | $CRYPTSETUP luksFormat --type luks2 --luks2-metadata-size 16k --luks2-keyslots-size 4064k --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --force-password $DEV || fail echo $PWD | $CRYPTSETUP open $DEV $NAME || fail $CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" || skip "LUKS2 can't use keyring. Test skipped." -dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha1sum > $CHKS_KEYRING || fail +dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_KEYRING || fail echo $PWD | $CRYPTSETUP refresh $NAME --disable-keyring || fail $CRYPTSETUP status $NAME | grep -q -i "location:.*keyring" && fail "Key is still in keyring" -dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha1sum > $CHKS_DMCRYPT || fail +dd if=/dev/mapper/$NAME bs=1M iflag=direct status=none | sha256sum > $CHKS_DMCRYPT || fail diff $CHKS_DMCRYPT $CHKS_KEYRING || fail "Plaintext checksum mismatch (corruption)" echo "OK" diff --git a/tests/keyring-test b/tests/keyring-test index 3ed3aff..38abcfb 100755 --- a/tests/keyring-test +++ b/tests/keyring-test @@ -76,9 +76,9 @@ function test_and_prepare_keyring() { } [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." -which dmsetup >/dev/null 2>&1 || skip "Cannot find dmsetup, test skipped" -which keyctl >/dev/null 2>&1 || skip "Cannot find keyctl, test skipped" -modprobe dm-crypt || fail "dm-crypt failed to load" +command -v dmsetup >/dev/null || skip "Cannot find dmsetup, test skipped" +command -v keyctl >/dev/null || skip "Cannot find keyctl, test skipped" +modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" dm_crypt_keyring_support || skip "dm-crypt doesn't support kernel keyring, test skipped." test_and_prepare_keyring diff --git a/tests/loopaes-test b/tests/loopaes-test index 5c28be3..fdb4cd3 100755 --- a/tests/loopaes-test +++ b/tests/loopaes-test @@ -3,6 +3,9 @@ [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + # try to validate using loop-AES losetup/kernel if available LOSETUP_AES=/losetup-aes.old @@ -37,10 +40,23 @@ function fail() function skip() { + remove_mapping [ -n "$1" ] && echo "$1" exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + function prepare() { remove_mapping @@ -143,7 +159,9 @@ function check_version() [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped." -which uuencode >/dev/null 2>&1 || skip "WARNING: test require uuencode binary, test skipped." +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run +command -v uuencode >/dev/null || skip "WARNING: test require uuencode binary, test skipped." check_version || skip "Probably old kernel, test skipped." # loop-AES tests diff --git a/tests/luks1-compat-test b/tests/luks1-compat-test index 311a559..18afcd5 100755 --- a/tests/luks1-compat-test +++ b/tests/luks1-compat-test @@ -1,22 +1,20 @@ #!/bin/bash -# check luks1 images parsing - -# NOTE: if image with whirlpool hash fails, check -# that you are not using old gcrypt with flawed whirlpool -# (see cryptsetup debug output) - [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup TST_DIR=luks1-images MAP=luks1tst KEYFILE=keyfile1 +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + [ -z "$srcdir" ] && srcdir="." function remove_mapping() { [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP + rm -rf $TST_DIR } function fail() @@ -32,21 +30,37 @@ function fail() function skip() { [ -n "$1" ] && echo "$1" - echo "Test skipped." + remove_mapping exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +function remove_imgs() +{ + echo "WARNING: $1 not available, not testing some images." + rm $(ls $TST_DIR/*$1*.img) +} + function test_one() { - $CRYPTSETUP benchmark -c "$1" -s "$2" | grep -v "#" || skip + $CRYPTSETUP benchmark -c "$1" -s "$2" | grep -v "#" || remove_imgs $1 } function test_required() { - which lsblk >/dev/null 2>&1 || skip "WARNING: lsblk tool required." - echo "REQUIRED KDF TEST" - $CRYPTSETUP benchmark -h whirlpool | grep "N/A" && skip + $CRYPTSETUP benchmark -h whirlpool | grep "N/A" && remove_imgs whirlpool echo "REQUIRED CIPHERS TEST" echo "# Algorithm | Key | Encryption | Decryption" @@ -59,9 +73,11 @@ function test_required() } export LANG=C - -test_required +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +command -v blkid >/dev/null || skip "blkid tool required, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run [ ! -d $TST_DIR ] && tar xJf $srcdir/luks1-images.tar.xz --no-same-owner +test_required echo "PASSPHRASE CHECK" for file in $(ls $TST_DIR/luks1_*) ; do @@ -80,6 +96,7 @@ done if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run activation part of test, test skipped." + remove_mapping exit 0 fi @@ -97,8 +114,11 @@ for file in $(ls $TST_DIR/luks1_*) ; do [ $ret -ne 0 ] && fail $CRYPTSETUP status $MAP >/dev/null || fail $CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail - UUID=$(lsblk -n -o UUID /dev/mapper/$MAP) + UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) $CRYPTSETUP remove $MAP || fail [ "$UUID" != "DEAD-BABE" ] && fail "UUID check failed." echo " [OK]" done + +remove_mapping +exit 0 diff --git a/tests/luks2-integrity-test b/tests/luks2-integrity-test index 0ba4b67..a8082f8 100755 --- a/tests/luks2-integrity-test +++ b/tests/luks2-integrity-test @@ -6,10 +6,14 @@ CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup DEV_NAME=dmi_test DEV=mode-test.img +HEADER_IMG=mode-test-detached.img PWD1=nHjJHjI23JK KEY_FILE=key.img FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + dmremove() { # device udevadm settle >/dev/null 2>&1 dmsetup remove $1 >/dev/null 2>&1 @@ -18,7 +22,7 @@ dmremove() { # device cleanup() { [ -b /dev/mapper/$DEV_NAME ] && dmremove $DEV_NAME [ -b /dev/mapper/"$DEV_NAME"_dif ] && dmremove "$DEV_NAME"_dif - rm -f $DEV $KEY_FILE >/dev/null 2>&1 + rm -f $DEV $KEY_FILE $HEADER_IMG >/dev/null 2>&1 } fail() @@ -37,6 +41,18 @@ skip() exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + add_device() { cleanup dd if=/dev/urandom of=$KEY_FILE bs=1 count=512 >/dev/null 2>&1 @@ -44,10 +60,14 @@ add_device() { sync } -status_check() # name value +status_check() # name value [detached] { - #$CRYPTSETUP status $DEV_NAME - X=$($CRYPTSETUP status $DEV_NAME | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) + if [ -n "$3" ]; then + PARAMS="$DEV_NAME --header $HEADER_IMG" + else + PARAMS="$DEV_NAME" + fi + X=$($CRYPTSETUP status $PARAMS | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) if [ "$X" != "$2" ] ; then echo "[status FAIL]" echo " Expecting $1:$2 got \"$X\"." @@ -57,7 +77,6 @@ status_check() # name value dump_check() # name value { - #$CRYPTSETUP luksDump $DEV X=$($CRYPTSETUP luksDump $DEV | grep -m1 "$1" | sed -e 's/.*:[ \t]\+//' | cut -d' ' -f1) if [ "$X" != "$2" ] ; then echo "[dump FAIL]" @@ -80,7 +99,6 @@ int_check_sum() # alg checksum int_error_detection() # alg int sector_size { - # FIXME: this is just a trivial failure echo -n "[DETECT_CORRUPTION]" echo -n "XXXXX" | dd of=$DEV bs=1M seek=28 count=1 conv=notrunc >/dev/null 2>&1 || fail "Cannot write to device." $CRYPTSETUP open -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device." @@ -88,7 +106,7 @@ int_error_detection() # alg int sector_size $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." } -intformat() # alg integrity integrity_out key_size int_key_size sector_size csum +intformat() # alg integrity integrity_out key_size int_key_size sector_size csum [test_hdr] { echo -n "[$1:$2:$4:$6]" echo -n "[FORMAT]" @@ -112,20 +130,39 @@ intformat() # alg integrity integrity_out key_size int_key_size sector_size csum int_check_sum $1 $7 echo -n "[REMOVE]" $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." + + # check detached header activation + if [ -n "$8" ] ; then + echo -n "[DETACHED_HDR]" + $CRYPTSETUP luksHeaderBackup -q --header-backup-file $HEADER_IMG $DEV || fail + wipefs -a $DEV >/dev/null 2>&1 || fail + $CRYPTSETUP open --header $HEADER_IMG -d $KEY_FILE $DEV $DEV_NAME || fail "Cannot activate device." + status_check "cipher" $1 1 + status_check "sector size" $6 1 + status_check "integrity:" $3 1 + status_check "keysize:" $(($4 + $5)) 1 + [ $5 -gt 0 ] && status_check "integrity keysize:" $5 1 + int_check_sum $1 $7 + $CRYPTSETUP close $DEV_NAME || fail "Cannot deactivate device." + $CRYPTSETUP luksHeaderRestore -q --header-backup-file $HEADER_IMG $DEV || fail + rm -f $HEADER_IMG + fi + int_error_detection echo "[OK]" } - [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run modprobe dm-integrity >/dev/null 2>&1 dmsetup targets | grep integrity >/dev/null 2>&1 || skip "Cannot find dm-integrity target, test skipped." +command -v wipefs >/dev/null || skip "Cannot find wipefs, test skipped." add_device -intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 128 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c -intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c +intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 128 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c 1 +intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 256 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c 1 intformat aes-xts-random hmac-sha256 hmac\(sha256\) 256 256 512 492c2d1cc9e222a850c399bfef4ed5a86bf5afc59e54f0f0c7ba8e2a64548323 intformat aes-cbc-essiv:sha256 hmac-sha256 hmac\(sha256\) 256 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c intformat aes-xts-plain64 hmac-sha256 hmac\(sha256\) 512 256 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c @@ -160,7 +197,7 @@ intformat chacha20-random poly1305 poly1305 256 0 512 5f6f3f6be03c74d9aaaeaf40 intformat chacha20-plain64 poly1305 poly1305 256 0 4096 7370c66a92708fb71b186931468be6aa9b26f4f88373b00b1c57360b9ee1304e intformat chacha20-random poly1305 poly1305 256 0 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b -intformat aegis128-random aead aead 128 0 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c -intformat aegis128-random aead aead 128 0 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b +intformat aegis128-random aead aead 128 0 512 ee501705a084cd0ab6f4a28014bcf62b8bfa3434de00b82743c50b3abf06232c 1 +intformat aegis128-random aead aead 128 0 4096 358d6beceddf593aff6b22c31684e0df9c226330aff5812e060950215217d21b 1 cleanup diff --git a/tests/luks2-reencryption-mangle-test b/tests/luks2-reencryption-mangle-test index 8f308f5..5aa62e4 100755 --- a/tests/luks2-reencryption-mangle-test +++ b/tests/luks2-reencryption-mangle-test @@ -9,6 +9,7 @@ CRYPTSETUP_VALGRIND=../.libs/cryptsetup CRYPTSETUP_LIB_VALGRIND=../.libs IMG=reenc-mangle-data IMG_HDR=$IMG.hdr +IMG_HDR_BCP=$IMG_HDR.bcp IMG_JSON=$IMG.json KEY1=key1 DEV_NAME=reenc3492834 @@ -21,7 +22,7 @@ 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 + rm -f $IMG $IMG_HDR $IMG_HDR_BCP $IMG_JSON $KEY1 >/dev/null 2>&1 } function fail() @@ -43,15 +44,15 @@ function skip() function bin_check() { - which $1 >/dev/null 2>&1 || skip "WARNING: test require $1 binary, test skipped." + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." } function img_json_save() { + local _hdr=$IMG + [ -z "$1" ] || _hdr="$1" # 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 + $CRYPTSETUP luksDump --dump-json-metadata $_hdr | jq -c -M . | tr -d '\n' >$IMG_JSON } function img_json_dump() @@ -86,7 +87,6 @@ function img_prepare_raw() # $1 options 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 @@ -101,6 +101,7 @@ function _dd() # header mangle functions function img_update_json() { + local _hdr="$IMG" local LUKS2_BIN1_OFFSET=448 local LUKS2_BIN2_OFFSET=$((LUKS2_BIN1_OFFSET + $JSON_MSIZE)) local LUKS2_JSON_SIZE=$(($JSON_MSIZE - 4096)) @@ -113,24 +114,26 @@ function img_update_json() echo $JSON | tr -d '\n' >$IMG_JSON || fail fi + [ -z "$2" ] || _hdr="$2" + # 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)) + _dd if=/dev/zero of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=/dev/zero of=$_hdr 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)) + _dd if=$IMG_JSON of=$_hdr count=$LUKS2_JSON_SIZE seek=4096 + _dd if=$IMG_JSON of=$_hdr 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 + _dd if=/dev/zero of=$_hdr count=64 seek=$LUKS2_BIN1_OFFSET + _dd if=/dev/zero of=$_hdr 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 SUM1_HEX=$(_dd if=$_hdr count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM1_HEX | xxd -r -p | _dd of=$_hdr 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 + local SUM2_HEX=$(_dd if=$_hdr skip=$JSON_MSIZE count=$JSON_MSIZE | sha256sum | cut -d ' ' -f 1) + echo $SUM2_HEX | xxd -r -p | _dd of=$_hdr seek=$LUKS2_BIN2_OFFSET count=64 || fail img_hash_save } @@ -145,6 +148,12 @@ function img_check_ok() $CRYPTSETUP repair $IMG $CS_PARAMS || fail } +function img_check_dump_ok() +{ + $CRYPTSETUP luksDump $IMG >/dev/null || fail + img_check_fail +} + function img_check_fail() { if [ $(id -u) == 0 ]; then @@ -157,43 +166,21 @@ function img_check_fail() 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." + $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt --resilience none || fail +} + +function img_run_reenc_ok_data_shift() +{ + $CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS -q --disable-locks --force-offline-reencrypt || fail } 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." +$CRYPTSETUP_RAW reencrypt $IMG $CS_PWPARAMS --force-offline-reencrypt --disable-locks -q 2>/dev/null && fail "Reencryption passed (should have failed)." img_hash_unchanged } -function img_check_fail_repair_ok() +function img_check_fail_repair() { if [ $(id -u) == 0 ]; then $CRYPTSETUP open $CS_PWPARAMS $IMG $DEV_NAME 2>/dev/null && fail @@ -205,9 +192,20 @@ function img_check_fail_repair_ok() $CRYPTSETUP repair $IMG $CS_PARAMS || fail img_check_ok +} + +function img_check_fail_repair_ok() +{ + img_check_fail_repair img_run_reenc_ok } +function img_check_fail_repair_ok_data_shift() +{ + img_check_fail_repair + img_run_reenc_ok_data_shift +} + function valgrind_setup() { bin_check valgrind @@ -219,26 +217,20 @@ function valgrind_setup() 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 "$@" } -function expect_run() -{ - export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" - expect "$@" -} +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." 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"]' @@ -253,6 +245,25 @@ img_prepare img_update_json 'del(.digests."2") | .config.requirements.mandatory = ["online-reencrypt"]' img_check_fail_repair_ok +# Simulate future version of reencrypt flag (should pass luksDump) +img_prepare +img_update_json '.config.requirements.mandatory = ["online-reencrypt-v999"]' +img_check_dump_ok + +# Multiple reencrypt requirement flags makes LUKS2 invalid +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt-v999"]' +img_check_fail + +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt"]' +img_check_fail + +# just regular unknown requirement +img_prepare +img_update_json '.config.requirements.mandatory = .config.requirements.mandatory + ["online-reencrypt-v3X"]' +img_check_dump_ok + # This must fail for new releases echo "[2] Old reencryption in-progress (journal)" img_prepare @@ -380,7 +391,7 @@ img_update_json ' .digests."0".segments = ["0","2"] | .digests."1".segments = ["1","3"] | .config.requirements.mandatory = ["online-reencrypt"]' -img_check_fail_repair_ok +img_check_fail_repair_ok_data_shift # # NEW metadata (with reenc digest) @@ -402,7 +413,6 @@ 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" | @@ -502,5 +512,37 @@ img_update_json ' }' $CRYPTSETUP reencrypt $IMG $CS_PARAMS >/dev/null 2>&1 && fail +echo "[9] Decryption with datashift" +img_prepare_raw +$CRYPTSETUP reencrypt $CS_PARAMS --decrypt --init-only --force-offline-reencrypt --resilience checksum --header $IMG_HDR $IMG || fail +cp $IMG_HDR $IMG_HDR_BCP + +# change hash +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.hash = "sha12345"' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# change sector size +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.sector_size = 1024' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# replace with new resilience mode +img_json_save $IMG_HDR_BCP +img_update_json 'del(.keyslots."1".area.hash) | + del(.keyslots."1".sector_size) | + .keyslots."1".area.type = "datashift-journal"' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# downgrade reencryption requirement +img_json_save $IMG_HDR_BCP +img_update_json '.config.requirements.mandatory = ["online-reencrypt-v2"]' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + +# change datashift value +img_json_save $IMG_HDR_BCP +img_update_json '.keyslots."1".area.shift_size = (((.keyslots."1".area.shift_size | tonumber) - 4096) | tostring)' $IMG_HDR +$CRYPTSETUP reencrypt --header $IMG_HDR $IMG $CS_PARAMS --force-offline-reencrypt 2>/dev/null && fail + remove_mapping exit 0 diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test index 92f223d..a647a8c 100755 --- a/tests/luks2-reencryption-test +++ b/tests/luks2-reencryption-test @@ -1,6 +1,6 @@ #!/bin/bash -PS4='$LINENO:' +#PS4='$LINENO:' [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup @@ -17,14 +17,17 @@ DEVBIG="reenc2134" DEV_NAME=reenc9768 DEV_NAME2=reenc97682 IMG=reenc-data -IMG_HDR=/tmp/$IMG.hdr +IMG_HDR=$IMG.hdr +HEADER_LUKS2_PV=blkid-luks2-pv.img +IMG_FS=xfs_512_block_size.img KEY1=key1 VKEY1=vkey1 PWD1="93R4P4pIqAH8" PWD2="1cND4319812f" PWD3="1-9Qu5Ejfnqv" +DEV_LINK="reenc-test-link" -[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) function dm_crypt_features() { @@ -44,7 +47,7 @@ function dm_crypt_features() [ $VER_MIN -lt 14 ] && return DM_PERF_CPU=1 - if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then + if [ $VER_MIN -ge 17 ]; then DM_SECTOR_SIZE=1 fi } @@ -61,14 +64,14 @@ scsi_debug_teardown() { local _tries=15; while [ -b "$1" -a $_tries -gt 0 ]; do - rmmod scsi_debug 2> /dev/null + rmmod scsi_debug >/dev/null 2>&1 if [ -b "$1" ]; then sleep .1 _tries=$((_tries-1)) fi done - test ! -b "$1" || rmmod scsi_debug 2> /dev/null + test ! -b "$1" || rmmod scsi_debug >/dev/null 2>&1 } function remove_mapping() @@ -97,8 +100,8 @@ 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 $VKEY1 $DEVBIG >/dev/null 2>&1 - rmmod scsi_debug 2> /dev/null + rm -f $IMG $IMG_HDR $KEY1 $VKEY1 $DEVBIG $DEV_LINK $HEADER_LUKS2_PV $IMG_FS >/dev/null 2>&1 + rmmod scsi_debug >/dev/null 2>&1 scsi_debug_teardown $DEV } @@ -126,15 +129,19 @@ function fips_mode() function add_scsi_device() { scsi_debug_teardown $DEV - modprobe scsi_debug $@ delay=0 - if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 - fi - - sleep 1 - DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) - [ -b $DEV ] || fail "Cannot find $DEV." + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 77 + fi + + sleep 1 + DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $DEV ] || fail "Cannot find $DEV." } function open_crypt() # $1 pwd, $2 hdr @@ -148,14 +155,30 @@ function open_crypt() # $1 pwd, $2 hdr fi } +function wipe_dev_head() # $1 dev, $2 length (in MiBs) +{ + dd if=/dev/zero of=$1 bs=1M count=$2 conv=notrunc >/dev/null 2>&1 +} + function wipe_dev() # $1 dev { if [ -b $1 ] ; then blkdiscard --zeroout $1 2>/dev/null || dd if=/dev/zero of=$1 bs=1M conv=notrunc >/dev/null 2>&1 + if [ $# -gt 2 ]; then + dd if=/dev/urandom of=$1 bs=1M seek=$2 conv=notrunc >/dev/null 2>&1 + fi else local size=$(stat --printf="%s" $1) truncate -s 0 $1 - truncate -s $size $1 + if [ $# -gt 2 ]; then + local diff=$((size-$2*1024*1024)) + echo "size: $size, diff: $diff" + truncate -s $diff $1 + # wipe_dev_head $1 $((diff/(1024*1024))) + dd if=/dev/urandom of=$1 bs=1M seek=$2 size=$((diff/(1024*1024))) conv=notrunc >/dev/null 2>&1 + else + truncate -s $size $1 + fi fi } @@ -199,7 +222,7 @@ function preparebig() # $1 dev1_siz function check_hash_dev() # $1 dev, $2 hash { - HASH=$(sha256sum $1 | cut -d' ' -f 1) + HASH=$(sha1sum $1 | cut -d' ' -f 1) [ $HASH != "$2" ] && fail "HASH differs (expected: $2) (result $HASH)" } @@ -210,15 +233,16 @@ function check_hash() # $1 pwd, $2 hash, $3 hdr $CRYPTSETUP remove $DEV_NAME || fail } +function check_hash_dev_head() # $1 dev, $2 len, $3 hash +{ + local hash=$(dd if=$1 bs=512 count=$2 2>/dev/null | sha1sum | cut -d' ' -f1) + [ $hash != "$3" ] && fail "HASH differs (expected: $3) (result $hash)" +} + function check_hash_head() # $1 pwd, $2 len, $3 hash, $4 hdr { open_crypt $1 $4 - if [ -n "$4" ]; then - echo $1 | $CRYPTSETUP resize $DEV_NAME --size $2 --header $4 || fail - else - echo $1 | $CRYPTSETUP resize $DEV_NAME --size $2 || fail - fi - check_hash_dev /dev/mapper/$DEV_NAME $3 + check_hash_dev_head /dev/mapper/$DEV_NAME $2 $3 $CRYPTSETUP remove $DEV_NAME || fail } @@ -297,7 +321,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 >/dev/null 2>&1 && fail + echo $PWD1 | $CRYPTSETUP reencrypt $DEV $_hdr --hotzone-size 1M --resilience $2 --sector-size $1 --force-offline-reencrypt -q $FAST_PBKDF_ARGON >/dev/null 2>&1 && fail fix_writes $OVRDEV $OLD_DEV echo $PWD1 | $CRYPTSETUP -q repair $DEV $_hdr || fail @@ -411,6 +435,8 @@ function encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON || fail check_hash $PWD1 $3 $4 + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -441,6 +467,8 @@ function encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 $CRYPTSETUP close $DEV_NAME || fail + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -465,6 +493,8 @@ function decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest check_hash_dev $DEV $3 + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -495,9 +525,94 @@ function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail check_hash_dev $DEV $3 + [ -f $4 ] && rm -f $4 + echo "[OK]" } +function decrypt_recover() { # $1 hash, $2 hdr, $3 dev size, $4 resilience, $5 hotzone size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 --init-only $_maxhz >/dev/null || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + fix_writes $OVRDEV $OLD_DEV + + echo $PWD1 | $CRYPTSETUP -q repair $DEV --header $2 || fail + + $CRYPTSETUP luksDump $2 | grep -q "online-reencrypt" + if [ $? -eq 0 ]; then + check_hash $PWD1 $1 $2 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 $_res -q $FAST_PBKDF_ARGON || fail + fi + + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + +function decrypt_recover_online() { # $1 hash, $2 hdr, $3 dev size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 $_maxhz --init-only >/dev/null 2>&1 || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery during activation + echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME || fail + + check_hash_dev /dev/mapper/$DEV_NAME $1 + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q || fail + + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + +function decrypt_recover_online_moved() { # $1 hash, $2 hdr, $3 dev size + local _res="" + local _maxhz="" + test -z "$4" || _res="--resilience $4" + test -z "$5" || _maxhz="--hotzone-size $5" + echo -n "[${4:-default}]" + + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --decrypt --header $2 $_maxhz $_res --init-only >/dev/null 2>&1 || fail + + error_writes $OVRDEV $OLD_DEV $ERROFFSET $ERRLENGTH + echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $2 -q $_res >/dev/null 2>&1 && fail + $CRYPTSETUP status $DEV_NAME --header $2 | grep -q "reencryption: in-progress" || fail + $CRYPTSETUP close $DEV_NAME || fail + fix_writes $OVRDEV $OLD_DEV + + # recovery but activation fails due to last segment recovery makes it plaintext device + echo $PWD1 | $CRYPTSETUP open $DEV --header $2 $DEV_NAME 2>/dev/null && fail + + $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail + check_hash_dev_head $DEV $3 $1 + + [ -f $2 ] && rm -f $2 + + echo -n "[OK]" +} + # sector size (bytes) # reenc dev size (sectors) # reenc dev digest @@ -508,15 +623,27 @@ function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 function reencrypt_offline_fixed_size() { local _esz=$(($1>>9)) local _hdr="" + # round-up fixed size to megabytes + local _mbs=$((($2>>11)+1)) test -z "$7" || _hdr="--header $7" + if [ -z "$7" ]; then + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --offset 16384 $FAST_PBKDF_ARGON $DEV || fail + else + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $7 $FAST_PBKDF_ARGON $DEV || fail + fi + echo $PWD1 | $CRYPTSETUP open $_hdr $DEV $DEV_NAME || fail + wipe_dev_head /dev/mapper/$DEV_NAME $_mbs + $CRYPTSETUP close $DEV_NAME || fail + # reencrypt with fixed device size - echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --device-size $2s --resilience $4 || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --device-size $2s --resilience $4 --force-offline-reencrypt || fail + check_hash_head $PWD1 $2 $3 $7 wipe $PWD1 $7 # try to reencrypt device size + 1 encryption sector size - echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --sector-size $1 --init-only --force-offline-reencrypt || fail echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV $_hdr --device-size $(($5+_esz))s --resilience $4 2>/dev/null && fail check_hash $PWD1 $6 $7 @@ -543,6 +670,7 @@ function encrypt_offline_fixed_size() { wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --device-size $2s --resilience $4 || fail check_hash_head $PWD1 $2 $3 $7 + [ -f $7 ] && rm -f $7 # try to reencrypt device size + 1 encryption sector size wipe_dev $DEV @@ -552,12 +680,15 @@ function encrypt_offline_fixed_size() { # misaligned reencryption size if [ $_esz -gt 1 ]; then + [ -f $7 ] && rm -f $7 echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --init-only || fail echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $7 --device-size $(($2+_esz-1))s --resilience $4 2>/dev/null && fail $CRYPTSETUP luksDump $7 | grep -q "2: crypt" || fail $CRYPTSETUP luksDump $7 | grep -q "3: crypt" && fail check_hash $PWD1 $6 $7 fi + + [ -f $7 ] && rm -f $7 } # sector size (bytes) @@ -652,6 +783,8 @@ function reencrypt_online_fixed_size() { $CRYPTSETUP close $DEV_NAME || fail check_hash $PWD1 $6 $7 fi + + [ -n "$7" -a -f "$7" ] && rm -f $7 } function setup_luks2_env() { @@ -668,9 +801,23 @@ function setup_luks2_env() { $CRYPTSETUP close $DEV_NAME || fail } +function check_blkid() { + bin_check blkid + xz -dkf $HEADER_LUKS2_PV.xz + if ! $($CRYPTSETUP --version | grep -q "BLKID"); then + HAVE_BLKID=0 + elif $(blkid -p -n crypto_LUKS $HEADER_LUKS2_PV >/dev/null 2>&1); then + HAVE_BLKID=1 + xz -dkf $IMG_FS.xz + blkid $IMG_FS | grep -q BLOCK_SIZE && BLKID_BLOCK_SIZE_SUPPORT=1 + else + HAVE_BLKID=0 + fi +} + function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } @@ -680,11 +827,16 @@ function valgrind_run() INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } +function bin_check() +{ + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." +} + [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." fips_mode && skip "This test cannot be run in FIPS mode." -modprobe --dry-run scsi_debug || exit 77 -modprobe dm-crypt || fail "dm-crypt failed to load" +modprobe --dry-run scsi_debug >/dev/null 2>&1 || skip "This kernel seems to not support proper scsi_debug module, test skipped." +modprobe dm-crypt >/dev/null 2>&1 || fail "dm-crypt failed to load" modprobe dm-delay > /dev/null 2>&1 dm_crypt_features @@ -703,25 +855,36 @@ export LANG=C # REENCRYPTION tests # 28 MiBs of zeros (32MiBs - 4MiB LUKS2 header) -HASH1=f8280c81b347b01405277bf9e8bf0685ae8be863ff104797c65b7169f8203fd2 +HASH1=4da90c0638bd7d29ce3d0ace3df5ee99706c23da # 1 MiB of zeros -HASH2=30e14955ebf1352266dc2ff8067e68104607e750abb9d3b36582b8af909fcb58 +HASH2=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3 # 256 MiBs of zeros -HASH3=a6d72ac7690f53be6ae46ba88506bd97302a093f7108472bd9efc3cefda06484 +HASH3=7b91dbdc56c5781edf6c8847b4aa6965566c5c75 # 64 MiBs of zeroes -HASH4=3b6a07d0d404fab4e23b6d34bc6696a6a312dd92821332385e5af7c01c421351 +HASH4=44fac4bedde4df04b9572ac665d3ac2c5cd00c7d # 56 MiBs of zeroes -HASH5=8afcb7e7189ce4d112fd245eaa60c3cfcf5a5d5e1d6bf4eb85941d73ef8cfbd5 +HASH5=bcd8ce9b30a43b2dacdf479493c93e167ef60946 # 43 MiBs of zeroes -HASH6=39f7c6d38af574fe2c90ef400dfaba8ef8edccd11bdac998a3f8143a86837331 +HASH6=2cf8a5f40a2ab5373c5425d6071da480f1ce08e8 # 31 MiBs of zeroes -HASH7=18a393d1a505e22ccf3e29effe3005ea8627e4c36b7cca0e53f58121f49b67e1 +HASH7=7ed56dd14d2841cf169fe503d097be04192666bd # 60 MiBs of zeroes -HASH8=cf5ac69ca412f9b3b1a8b8de27d368c5c05ed4b1b6aa40e6c38d9cbf23711342 +HASH8=233ba936226a3ac499e67babaebd0d4aafb9761a +# 240 MiBs of zeroes (256MiBs - 16MiBs default LUKS2 header size) +HASH9=045eebed703cce308e049deb019b877f0445862f +# 16 MiBs of zeroes +HASH10=3b4417fc421cee30a9ad0fd9319220a8dae32da2 prepare dev_size_mb=32 setup_luks2_env +# Check that we can use other ciphers than AES in userspace backend. +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c twofish-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Twofish cipher, test skipped" +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c serpent-xts-plain64 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON 2>/dev/null || skip "Cannot use Serpent cipher, test skipped." +wipe_dev $DEV + echo "[1] Reencryption" echo -n "[512 sector]" echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-essiv:sha256 --offset 8192 $FAST_PBKDF_ARGON $DEV || fail @@ -747,7 +910,6 @@ echo -n "[OK][4096 sector]" prepare sector_size=4096 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 || fail check_hash $PWD1 $HASH1 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail @@ -770,7 +932,6 @@ echo -n "[OK][4096/512 sector]" prepare sector_size=512 physblk_exp=3 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 || fail check_hash $PWD1 $HASH1 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal $FAST_PBKDF_ARGON || fail @@ -797,7 +958,7 @@ check_hash $PWD1 $HASH2 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 128 -c aes-cbc-essiv:sha256 --resilience checksum $FAST_PBKDF_ARGON || fail check_hash $PWD1 $HASH2 if [ -n "$DM_SECTOR_SIZE" ]; then - echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON --sector-size 4096 || fail + echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q $FAST_PBKDF_ARGON --sector-size 4096 --force-offline-reencrypt || fail check_hash $PWD1 $HASH2 echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -s 256 -c twofish-cbc-essiv:sha256 --resilience journal --sector-size 2048 $FAST_PBKDF_ARGON || fail check_hash $PWD1 $HASH2 @@ -816,7 +977,6 @@ check_hash_dev $DEV $HASH4 echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON || fail check_hash_head $PWD1 $((56*1024*2)) $HASH5 wipe_dev $DEV -check_hash_dev $DEV $HASH4 echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c twofish-cbc-essiv:sha256 -s 128 --reduce-device-size 21M -q $FAST_PBKDF_ARGON || fail check_hash_head $PWD1 $((43*1024*2)) $HASH6 wipe_dev $DEV @@ -830,7 +990,7 @@ wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M -q $FAST_PBKDF_ARGON > /dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 8M --init-only -q $FAST_PBKDF_ARGON $DEV || fail resize_file $DEVBIG -512 -echo $PWD1 | $CRYPTSETUP reencrypt $DEV 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV 2> /dev/null && fail resize_file $DEVBIG 512 wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --offset 32760 --reduce-device-size 8M -q $FAST_PBKDF_ARGON --init-only >/dev/null 2>&1 && fail @@ -860,20 +1020,38 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail $CRYPTSETUP close $DEV_NAME echo $PWD1 | $CRYPTSETUP open $DEV --test-passphrase || fail +# Small device encryption test +preparebig 65 +# wipe only 1st MiB (final data size after encryption) +wipe_dev $DEV 1 +check_hash_dev_head $DEV 2048 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M -q $FAST_PBKDF_ARGON || fail +check_hash_head $PWD1 2048 $HASH2 + +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M --init-only -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail +check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q || fail +check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 + echo "[3] Encryption with detached header" preparebig 256 wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --resilience journal --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c twofish-cbc-essiv:sha256 -s 128 --resilience none --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c serpent-xts-plain --resilience checksum --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR # Device activation after encryption initialization wipe_dev $DEV @@ -885,6 +1063,14 @@ check_hash_dev /dev/mapper/$DEV_NAME $HASH3 echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON $DEV_NAME 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR + +# Device encryption with data offset set in detached header +wipe_dev $DEV +dd if=/dev/urandom of=$DEV bs=512 count=32768 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR --offset 32768 -q $FAST_PBKDF_ARGON $DEV || fail +check_hash $PWD1 $HASH9 $IMG_HDR +rm -f $IMG_HDR # Device activation using key file wipe_dev $DEV @@ -894,6 +1080,22 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail $CRYPTSETUP close $DEV_NAME echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail +# Encrypt without size reduction must not allow header device same as data device +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail +ln -s $DEV $DEV_LINK || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail +rm -f $DEV_LINK || fail + +dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1 +echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail +ln -s $IMG $DEV_LINK || fail +echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail + echo "[4] Reencryption with detached header" wipe $PWD1 $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail @@ -918,7 +1120,7 @@ $CRYPTSETUP close $DEV_NAME || fail $CRYPTSETUP close $DEV_NAME2 || fail echo "[5] Decryption with detached header" -echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --sector-size 512 -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --header $IMG_HDR $DEV || fail check_hash_dev $DEV $HASH3 @@ -936,7 +1138,7 @@ echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience checksum --header $ check_hash_dev $DEV $HASH3 # check deferred remove works as expected after decryption -echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 -c serpent-xts-plain --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --sector-size 512 -c serpent-xts-plain --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail open_crypt $PWD1 $IMG_HDR dmsetup create $DEV_NAME2 --table "0 1 linear /dev/mapper/$DEV_NAME 0" || fail echo $PWD1 | $CRYPTSETUP reencrypt -q --decrypt --resilience checksum --header $IMG_HDR --active-name $DEV_NAME || fail @@ -946,15 +1148,30 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail # check tool can block some funny user ideas preparebig 64 +ln -s $DEV $DEV_LINK || fail 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 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $DEV_LINK -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 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --active-name $DEV_NAME --header $DEV_LINK -q 2>/dev/null && fail $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail $CRYPTSETUP close $DEV_NAME +# yet another funny idea +rm -f $IMG_HDR +$CRYPTSETUP luksHeaderBackup --header-backup-file $IMG_HDR $DEV || fail +chmod +w $IMG_HDR || fail +command -v wipefs >/dev/null && { + wipefs -a $DEV >/dev/null 2>&1 || fail +} +open_crypt $PWD1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --active-name $DEV_NAME --decrypt --header $IMG_HDR -q 2>/dev/null && fail +$CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail +$CRYPTSETUP close $DEV_NAME || fail + if ! dm_delay_features; then echo "dm-delay target is missing, skipping recovery tests." remove_mapping @@ -972,7 +1189,6 @@ echo "sector size 512->512" get_error_offsets 32 $OFFSET echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --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 @@ -984,13 +1200,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 32 $OFFSET 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 - 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 --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" @@ -998,7 +1212,6 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 32 $OFFSET 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --sector-size 4096 -c aes-cbc-essiv:sha256 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 - check_hash $PWD1 $HASH1 echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover 4096 checksum $HASH1 @@ -1012,7 +1225,6 @@ echo "sector size 512->512" get_error_offsets 32 $OFFSET echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --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 512 checksum $HASH1 @@ -1024,13 +1236,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 32 $OFFSET 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 - 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 --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" @@ -1038,7 +1248,6 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 32 $OFFSET 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --sector-size 4096 -c aes-cbc-essiv:sha256 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 - check_hash $PWD1 $HASH1 echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover_online 4096 checksum $HASH1 @@ -1065,13 +1274,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 31 0 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover 4096 checksum $HASH7 $IMG_HDR echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR reencrypt_recover 4096 journal $HASH7 $IMG_HDR echo "sector size 4096->4096" @@ -1079,7 +1286,6 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 31 0 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover 4096 checksum $HASH7 $IMG_HDR @@ -1093,7 +1299,6 @@ echo "sector size 512->512" get_error_offsets 31 0 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR -check_hash $PWD1 $HASH7 $IMG_HDR echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover_online 512 checksum $HASH7 $IMG_HDR @@ -1105,13 +1310,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 31 0 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover_online 4096 checksum $HASH7 $IMG_HDR echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR reencrypt_recover_online 4096 journal $HASH7 $IMG_HDR echo "sector size 4096->4096" @@ -1119,7 +1322,6 @@ if [ -n "$DM_SECTOR_SIZE" ]; then get_error_offsets 31 0 4096 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 $IMG_HDR - check_hash $PWD1 $HASH7 $IMG_HDR echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" reencrypt_recover_online 4096 checksum $HASH7 $IMG_HDR @@ -1251,30 +1453,27 @@ fi echo "[16] Offline reencryption with fixed device size." preparebig 68 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --offset 16384 $FAST_PBKDF_ARGON $DEV || fail -wipe $PWD1 -check_hash $PWD1 $HASH8 -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - reencrypt_offline_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 - reencrypt_offline_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 - reencrypt_offline_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 + reencrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 + reencrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 + reencrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 echo -n "[OK]" done echo "" done echo "[17] Online reencryption with fixed device size." -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - reencrypt_online_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 - reencrypt_online_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 - reencrypt_online_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 + reencrypt_online_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 + reencrypt_online_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 + reencrypt_online_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 echo -n "[OK]" done echo "" @@ -1282,43 +1481,40 @@ done echo "[18] Offline reencryption with fixed device size (detached header)." preparebig 60 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail -wipe $PWD1 $IMG_HDR -check_hash $PWD1 $HASH8 $IMG_HDR -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - reencrypt_offline_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - reencrypt_offline_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - reencrypt_offline_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR echo -n "[OK]" done echo "" done echo "[19] Online reencryption with fixed device size (detached header)." -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - reencrypt_online_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - reencrypt_online_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - reencrypt_online_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_online_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_online_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + reencrypt_online_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR echo -n "[OK]" done echo "" done echo "[20] Offline encryption with fixed device size (detached header)." -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - encrypt_offline_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - encrypt_offline_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - encrypt_offline_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + encrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + encrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + encrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR echo -n "[OK]" done echo "" @@ -1326,13 +1522,13 @@ done echo "[21] Offline decryption with fixed device size (detached header)." prepare_linear_dev 60 -for test_ss in $TEST_SECTORS; do -printf "sector size %4s: " $test_ss +for test_sector_size in $TEST_SECTORS; do +printf "sector size %4s: " $test_sector_size for test_res in checksum journal none; do echo -n "[$test_res]" - decrypt_offline_fixed_size $test_ss 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - decrypt_offline_fixed_size $test_ss $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR - decrypt_offline_fixed_size $test_ss $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + decrypt_offline_fixed_size $test_sector_size 2048 $HASH2 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + decrypt_offline_fixed_size $test_sector_size $((28*1024*2)) $HASH1 $test_res $((60*1024*2)) $HASH8 $IMG_HDR + decrypt_offline_fixed_size $test_sector_size $((31*1024*2)) $HASH7 $test_res $((60*1024*2)) $HASH8 $IMG_HDR echo -n "[OK]" done echo "" @@ -1344,7 +1540,6 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --offset 32768 $FAST_PBKDF_A echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF2 $DEV || fail echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON $DEV || fail wipe $PWD1 -check_hash $PWD1 $HASH2 echo -e "$PWD1\n$PWD2\n$PWD3" | $CRYPTSETUP reencrypt $DEV -q || fail check_hash $PWD1 $HASH2 @@ -1403,16 +1598,33 @@ 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 +#test error path behaves as expected for initialization with not enough space in binary area +# create LUKS2 header with keyslots binary space for exactly 4 keyslots +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --luks2-keyslots-size $((4*258048)) -S0 -s512 --cipher aes-xts-plain64 $FAST_PBKDF_ARGON $DEV >/dev/null || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -S1 $DEV -q $FAST_PBKDF_ARGON || fail +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey -S2 $DEV -q $FAST_PBKDF_ARGON || fail +# there is not enough space in binary area for keyslot id 4 (replacement for id 2) +echo -e "$PWD1\n$PWD2\n$PWD2" | $CRYPTSETUP reencrypt $DEV --init-only -q 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +# check cli removed all unbound keyslots created in-before reencryption initialization +$CRYPTSETUP luksDump $DEV | grep -q "unbound" && fail + +echo $PWD1 | $CRYPTSETUP luksKillSlot $DEV 2 || fail +# there is not enough space in binary area for reencryption keyslot +echo -e "$PWD1\n$PWD2" | $CRYPTSETUP reencrypt $DEV --init-only -q 2>/dev/null && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +# check cli removed all unbound keyslots created in-before reencryption initialization +$CRYPTSETUP luksDump $DEV | grep -q "unbound" && 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 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q -S0 $FAST_PBKDF_ARGON --volume-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 +echo $PWD1 | $CRYPTSETUP luksAddKey -q $FAST_PBKDF_ARGON --volume-key-file $VKEY1 -s 128 $DEV || fail check_hash $PWD1 $HASH1 echo "[24] Reencryption with initial cipher_null" @@ -1420,7 +1632,6 @@ echo "[24] Reencryption with initial cipher_null" 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 @@ -1469,7 +1680,6 @@ 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 @@ -1483,13 +1693,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then 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" @@ -1497,7 +1705,6 @@ if [ -n "$DM_SECTOR_SIZE" ]; then 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 @@ -1511,7 +1718,6 @@ 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 @@ -1525,13 +1731,11 @@ if [ -n "$DM_SECTOR_SIZE" ]; then 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" @@ -1539,12 +1743,465 @@ if [ -n "$DM_SECTOR_SIZE" ]; then 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 +echo "[27] Verify test passphrase mode works with reencryption metadata" +echo $PWD1 | $CRYPTSETUP -S5 -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --init-only $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail + +echo $PWD1 | $CRYPTSETUP -q luksFormat -S5 --header $IMG_HDR --type luks2 $FAST_PBKDF_ARGON $DEV || fail +echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $IMG_HDR || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --init-only --header $IMG_HDR $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail +rm -f $IMG_HDR +wipe_dev_head $DEV 1 + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --init-only --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail + +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 8M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail + +echo "[28] Prevent nested encryption" +prepare_linear_dev 32 opt_blks=64 $OPT_XFERLEN_EXP + +#device already LUKS2 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --reduce-device-size 2m $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --reduce-device-size 2m $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +#type mismatch +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 $DEV 2>/dev/null && fail +wipe_dev $DEV + +#detached header already LUKS2 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 --header $IMG_HDR $DEV 2>/dev/null && fail +rm -f $IMG_HDR + +#data device already in reencryption +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --init-only $FAST_PBKDF_ARGON $DEV || fail + +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail +test -f $IMG_HDR && fail +#type mismatch +echo $PWD1 | $CRYPTSETUP reencrypt -q --type luks1 $DEV 2>/dev/null && fail +wipe_dev $DEV +rm -f $IMG_HDR + +#header in reencryption (type mismatch) +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --type luks1 --header $IMG_HDR $FAST_PBKDF2 $DEV 2>/dev/null && fail + +echo "[29] Conflicting reencryption parameters" +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --reduce-device-size 4M $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-checksum 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-journal 2> /dev/null && fail +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 16M $DEV -q $FAST_PBKDF_ARGON 2> /dev/null || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience journal 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-checksum 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --resilience datashift-journal 2> /dev/null && fail +wipe_dev_head $DEV 1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --resilience datashift-checksum 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --resilience datashift-journal 2>/dev/null && fail +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --encrypt --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --header $IMG_HDR $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only $FAST_PBKDF_ARGON || fail +echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR $DEV -q $FAST_PBKDF_ARGON 2> /dev/null && fail +rm -f $IMG_HDR +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF2 $DEV || fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience datashift 2> /dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience none 2> /dev/null && fail +test -f $IMG_HDR && fail +$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience checksum --hotzone-size 4m || fail +$CRYPTSETUP isLuks $DEV -q && fail +# $CRYPTSETUP luksDump $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience datashift 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience none 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience journal || fail +rm -f $IMG_HDR + +check_blkid +if [ "$HAVE_BLKID" -gt 0 ]; then + echo "[30] Prevent nested encryption of broken LUKS device" + rm -f $IMG_HDR + xz -dkf $HEADER_LUKS2_PV.xz + wipe_dev $DEV + + # broken header + echo $PWD1 | $CRYPTSETUP reencrypt -q --header $HEADER_LUKS2_PV $DEV $FAST_PBKDF_ARGON --encrypt --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken device + echo $PWD1 | $CRYPTSETUP reencrypt -q $HEADER_LUKS2_PV $FAST_PBKDF_ARGON --encrypt --force-offline-reencrypt --type luks2 --reduce-device-size 8m 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken data device only + echo $PWD1 | $CRYPTSETUP reencrypt -q --header $IMG_HDR $HEADER_LUKS2_PV $FAST_PBKDF_ARGON --encrypt --force-offline-reencrypt --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail +fi + +if [ -n "$DM_SECTOR_SIZE" -a $HAVE_BLKID -gt 0 ]; then + echo "[31] Prevent dangerous sector size increase" + preparebig 64 + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 512 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + + # block encryption sector size increase on offline device + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 1024" && fail + + # --force-offline-reencrypt can bypass the constraint + echo $PWD1 | $CRYPTSETUP reencrypt --force-offline-reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV || fail + # resume must work + echo $PWD1 | $CRYPTSETUP reencrypt -q $FAST_PBKDF_ARGON $DEV || fail + + # online with no superblock is fine + echo $PWD1 | $CRYPTSETUP open -q $DEV $DEV_NAME || fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 4096 $FAST_PBKDF_ARGON $DEV || fail + $CRYPTSETUP close $DEV_NAME || fail + + # sector size decrease is ok + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 4096 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV || fail + + if [ -n "$BLKID_BLOCK_SIZE_SUPPORT" ]; then + xz -dkf $IMG_FS.xz + # encryption checks must work in offline mode + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --header $IMG_HDR $IMG_FS $FAST_PBKDF_ARGON --init-only --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail + + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --header $IMG_HDR $IMG_FS $FAST_PBKDF_ARGON --type luks2 2>/dev/null && fail + test -f $IMG_HDR && fail + + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --reduce-device-size 8m $IMG_FS $FAST_PBKDF_ARGON --init-only --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $IMG_FS && fail + echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --force-offline-reencrypt --sector-size 1024 -q --reduce-device-size 8m $IMG_FS $FAST_PBKDF_ARGON --type luks2 2>/dev/null && fail + $CRYPTSETUP isLuks $IMG_FS && fail + + echo $PWD1 | $CRYPTSETUP luksFormat -q --sector-size 512 --type luks2 $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open -q $DEV $DEV_NAME || fail + dd if=$IMG_FS of=/dev/mapper/$DEV_NAME bs=1M >/dev/null 2>&1 + + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail + echo $PWD1 | $CRYPTSETUP reencrypt --init-only -q --sector-size 1024 --active-name $DEV_NAME $FAST_PBKDF_ARGON 2>/dev/null && fail + $CRYPTSETUP status $DEV_NAME | grep -q "reencryption: in-progress" && fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 $FAST_PBKDF_ARGON $DEV 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 512" || fail + echo $PWD1 | $CRYPTSETUP reencrypt -q --sector-size 1024 --active-name $DEV_NAME $FAST_PBKDF_ARGON 2>/dev/null && fail + $CRYPTSETUP luksDump $DEV | grep -q "sector: 512" || fail + fi +fi + +echo "[32] Removal of encryption (LUKS2 legacy cryptsetup-reencrypt test)." +prepare dev_size_mb=32 +OFFSET=8192 + +# offline decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# online decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# offline decryption (separate initialization and decryption steps) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash $PWD1 $HASH1 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# online decryption with shift +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 57344 $HASH1 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# same tests just with date size == LUKS2 header size +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +wipe $PWD1 +check_hash $PWD1 $HASH10 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash $PWD1 $HASH10 $IMG_HDR +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 32768 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH10 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 32768 $HASH10 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +# 1MiB data size +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 63488 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +# --hotzone-size larger than data expected to get auto corrected by library +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only --hotzone-size 4M || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# small device (less than header size) +prepare dev_size_mb=5 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +# FIXME: Should not reencryption remove it automatically? +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# initialization by --active-name parameter +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --active-name $DEV_NAME || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +# initialization and resume by --active-name parameter +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --active-name $DEV_NAME --init-only || fail +check_hash_dev /dev/mapper/$DEV_NAME $HASH2 +echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --header $IMG_HDR --active-name $DEV_NAME || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +echo "[33] Decryption with datashift recovery (error in shift area)." +prepare_linear_dev 32 +echo "sector size 512" + +# avoid error in moved segment area on purpose +# Also do not create write error in last segment because +# that would not trigger reencryption crash (read would pass) +get_error_offsets 32 $OFFSET 512 $((32-1024*2-$OFFSET)) +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 + +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" +echo -n "resilience:" +decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 $OFFSET 4096 $((32-1024*2-$OFFSET)) + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + echo -n "resilience:" + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) +fi +echo "" + +echo "[34] Decryption with datashift recovery (error in moved segment)." +echo "sector size 512" + +HZ_SIZE=$((3*1024*2)) + +# move injected error in moved segment area +get_error_offsets 32 0 512 $HZ_SIZE +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) +done + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + # move injected error in moved segment area + get_error_offsets 32 0 4096 $HZ_SIZE + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + + echo -n "resilience:" + for res in datashift-journal datashift-checksum; do + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + wipe $PWD1 + + decrypt_recover $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) + done +fi +echo "" + +echo "[35] Decryption with datashift recovery (online i/o error in shift area)." +echo "sector size 512" + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail +wipe_dev /dev/mapper/$DEV_NAME + +# avoid error in moved segment area on purpose +# Also do not create write error in last segment because +# that would not trigger reencryption crash (read would pass) +get_error_offsets 32 $OFFSET 512 $((32-1024*2-$OFFSET)) +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +decrypt_recover_online $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 $OFFSET 4096 $((32-1024*2-$OFFSET)) + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + echo -n "resilience:" + decrypt_recover_online $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) +fi +echo "" + +echo "[36] Decryption with datashift recovery (online i/o error in moved segment)." +echo "sector size 512" + +# move injected error in moved segment area +get_error_offsets 32 0 512 $HZ_SIZE +echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + +echo -n "resilience:" +for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + decrypt_recover_online_moved $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) +done + +if [ -n "$DM_SECTOR_SIZE" ]; then + echo -e "\nsector size 4096" + + get_error_offsets 32 0 4096 $HZ_SIZE + echo "ERR writes to sectors [$ERROFFSET,$(($ERROFFSET+$ERRLENGTH-1))]" + + echo -n "resilience:" + for res in datashift-journal datashift-checksum; do + + echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 4096 --offset $OFFSET $FAST_PBKDF_ARGON $DEV || fail + echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail + wipe_dev /dev/mapper/$DEV_NAME + + decrypt_recover_online_moved $HASH1 $IMG_HDR $((32*1024*2-$OFFSET)) $res $(($HZ_SIZE*512)) + done +fi +echo "" + +echo "[37] Decryption with datashift (large data offsets)" +prepare_linear_dev 512 + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1015808 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV $((16*1024*2)) $HASH10 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1015808 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV $((16*1024*2)) $HASH10 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1046528 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +wipe $PWD1 +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV 2048 $HASH2 +rm -f $IMG_HDR + +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --sector-size 512 --offset 1046528 --luks2-keyslots-size 16M $FAST_PBKDF_ARGON $DEV || fail +echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME +wipe_dev /dev/mapper/$DEV_NAME +echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --header $IMG_HDR $DEV -q || fail +check_hash_dev_head $DEV 2048 $HASH2 + remove_mapping exit 0 diff --git a/tests/luks2-validation-test b/tests/luks2-validation-test index 04183fb..cd9f0a6 100755 --- a/tests/luks2-validation-test +++ b/tests/luks2-validation-test @@ -80,7 +80,9 @@ function test_load() else $CRYPTSETUP luksDump $_debug $IMG > /dev/null 2>&1 fi - test $? -ne 0 || return 1 + ret=$? + test $ret -ne 0 || return 1 + test $ret -ne 139 || return 1 ;; *) fail "Internal test error" @@ -102,7 +104,7 @@ function RUN() function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } @@ -112,9 +114,10 @@ function valgrind_run() INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." [ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run -which jq >/dev/null 2>&1 || skip "Cannot find jq, test skipped." +command -v jq >/dev/null || skip "Cannot find jq, test skipped." prepare @@ -129,27 +132,27 @@ cd $START_DIR echo "[1] Test basic auto-recovery" RUN luks2-invalid-checksum-hdr0.img "R" "Failed to recover from trivial header corruption at offset 0" -# TODO: check epoch is incresed after recovery +# TODO: check epoch is increased after recovery # TODO: check only sectors related to corrupted hdr at offset 0 are written (dmstats tool/differ.c) RUN luks2-invalid-checksum-hdr1.img "R" "Failed to recover from trivial header corruption at offset 16384" -# TODO: check epoch is incresed after recovery +# TODO: check epoch is increased after recovery # TODO: check only sectors related to corrupted hdr at offset 16384 are written (dmstats tool/differ.c) RUN luks2-invalid-checksum-both-hdrs.img "F" "Failed to recognise corrupted header beyond repair" echo "[2] Test ability to auto-correct mallformed json area" RUN luks2-corrupted-hdr0-with-correct-chks.img "R" "Failed to auto correct malformed json area at offset 512" -# TODO: check epoch is incresed after recovery +# TODO: check epoch is increased after recovery # TODO: check only sectors related to corrupted hdr at offset 0 are written (dmstats tool/differ.c) RUN luks2-corrupted-hdr1-with-correct-chks.img "R" "Failed to auto correct malformed json area at offset 16896" -# TODO: check epoch is incresed after recovery +# TODO: check epoch is increased after recovery # TODO: check only sectors related to corrupted hdr at offset 16384 are written (dmstats tool/differ.c) RUN luks2-correct-full-json0.img "R" "Failed to parse full and correct json area" # TODO: detect noop (norecovery, epoch untouched) -# TODO: check epoch is NOT incresed after recovery of secondary header +# TODO: check epoch is NOT increased after recovery of secondary header # these tests auto-correct json in-memory only. It'll get fixed on-disk after write operation RUN luks2-argon2-leftover-params.img "R" "Failed to repair keyslot with old argon2 parameters." @@ -201,6 +204,7 @@ 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" +RUN luks2-segment-crypt-empty-encryption.img "F" "Failed to detect empty encryption field" 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" @@ -229,6 +233,16 @@ RUN luks2-metadata-size-512k-secondary.img "R" "Valid 512KiB metadata size in s RUN luks2-metadata-size-1m-secondary.img "R" "Valid 1MiB metadata size in secondary hdr failed to validate" RUN luks2-metadata-size-2m-secondary.img "R" "Valid 2MiB metadata size in secondary hdr failed to validate" RUN luks2-metadata-size-4m-secondary.img "R" "Valid 4MiB metadata size in secondary hdr failed to validate" +RUN luks2-metadata-size-invalid.img "F" "Invalid metadata size in secondary hdr not rejected" +RUN luks2-metadata-size-invalid-secondary.img "F" "Invalid metadata size in secondary hdr not rejected" + +echo "[7] Test invalid metadata object property" +RUN luks2-invalid-tokens.img "F" "Invalid tokens objects not rejected" +RUN luks2-invalid-top-objects.img "F" "Invalid top-level objects not rejected" +RUN luks2-keyslot-invalid-area.img "F" "Invalid keyslot area object not rejected" +RUN luks2-keyslot-invalid-area-size.img "F" "Invalid keyslot area size that can overflow not rejected" +RUN luks2-keyslot-invalid-objects.img "F" "Invalid keyslot objects not rejected" +RUN luks2-keyslot-invalid-af.img "F" "Invalid keyslot objects types not rejected" remove_mapping diff --git a/tests/luks2_header_requirements.tar.xz b/tests/luks2_header_requirements.tar.xz Binary files differnew file mode 100644 index 0000000..b198fd5 --- /dev/null +++ b/tests/luks2_header_requirements.tar.xz diff --git a/tests/luks2_header_requirements.xz b/tests/luks2_header_requirements.xz Binary files differdeleted file mode 100644 index eaaa73c..0000000 --- a/tests/luks2_header_requirements.xz +++ /dev/null diff --git a/tests/luks2_header_requirements_free.xz b/tests/luks2_header_requirements_free.xz Binary files differdeleted file mode 100644 index 7617ee6..0000000 --- a/tests/luks2_header_requirements_free.xz +++ /dev/null diff --git a/tests/mode-test b/tests/mode-test index d16482f..82171fb 100755 --- a/tests/mode-test +++ b/tests/mode-test @@ -8,6 +8,7 @@ DEV_NAME=dmc_test HEADER_IMG=mode-test.img PASSWORD=3xrododenron PASSWORD1=$PASSWORD +FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" # cipher-chainmode-ivopts:ivmode CIPHERS="aes twofish serpent" @@ -16,16 +17,16 @@ IVMODES="null benbi plain plain64 essiv:sha256" LOOPDEV=$(losetup -f 2>/dev/null) +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + dmremove() { # device udevadm settle >/dev/null 2>&1 dmsetup remove --retry $1 >/dev/null 2>&1 } cleanup() { - for dev in $(dmsetup status --target crypt | sed s/\:\ .*// | grep "^$DEV_NAME"_); do - dmremove $dev - sleep 2 - done + [ -b /dev/mapper/"$DEV_NAME"_tstdev ] && dmremove "$DEV_NAME"_tstdev [ -b /dev/mapper/$DEV_NAME ] && dmremove $DEV_NAME losetup -d $LOOPDEV >/dev/null 2>&1 rm -f $HEADER_IMG >/dev/null 2>&1 @@ -46,6 +47,19 @@ skip() exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + + add_device() { cleanup dd if=/dev/zero of=$HEADER_IMG bs=1M count=6 >/dev/null 2>&1 @@ -113,14 +127,14 @@ dmcrypt() echo -n "[n/a]" fi - echo $PASSWORD | $CRYPTSETUP luksFormat --type luks1 -i 1 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1 + echo $PASSWORD | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF2 -c $1 -s 256 /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then echo -n -e " LUKS1:" echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1 || fail dmcrypt_check "$DEV_NAME"_tstdev $OUT fi - echo $PASSWORD | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 -i 1 -c $1 -s 256 --offset 8192 /dev/mapper/$DEV_NAME >/dev/null 2>&1 + echo $PASSWORD | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 $FAST_PBKDF2 -c $1 -s 256 --offset 8192 /dev/mapper/$DEV_NAME >/dev/null 2>&1 if [ $? -eq 0 ] ; then echo -n -e " LUKS2:" echo $PASSWORD | $CRYPTSETUP luksOpen /dev/mapper/$DEV_NAME "$DEV_NAME"_tstdev >/dev/null 2>&1 || fail @@ -138,6 +152,8 @@ dmcrypt() [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ -z "$LOOPDEV" ] && skip "Cannot find free loop device, test skipped." +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run add_device diff --git a/tests/password-hash-test b/tests/password-hash-test index 0fb58b3..6e3c78c 100755 --- a/tests/password-hash-test +++ b/tests/password-hash-test @@ -9,6 +9,9 @@ KEY_FILE=keyfile DEV2=$DEV_NAME"_x" +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + dmremove() { # device udevadm settle >/dev/null 2>&1 dmsetup remove --retry $1 >/dev/null 2>&1 @@ -23,12 +26,30 @@ cleanup() { function fail() { - echo " $1 [FAILED]" + echo " $1 [FAILED]" echo "FAILED backtrace:" while caller $frame; do ((frame++)); done cleanup 2 } +skip() +{ + echo "TEST SKIPPED: $1" + cleanup 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + crypt_key() # hash keysize pwd/file name outkey [limit] [offset] { DEV2=$DEV_NAME"_x" @@ -75,7 +96,7 @@ crypt_key() # hash keysize pwd/file name outkey [limit] [offset] esac # ignore these cases, not all libs/kernel supports it - if [ "$1" != "sha1" -a "$1" != "sha256" ] || [ $2 -gt 256 ] ; then + if [ "$1" != "sha256" ] || [ $2 -gt 256 ] ; then if [ $ret -ne 0 ] ; then echo " [N/A] ($ret, SKIPPED)" return @@ -95,6 +116,8 @@ crypt_key() # hash keysize pwd/file name outkey [limit] [offset] dmremove $DEV2 } +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run this test, test skipped." exit 77 diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test index 6dc85bd..453831d 100755 --- a/tests/reencryption-compat-test +++ b/tests/reencryption-compat-test @@ -2,14 +2,20 @@ [ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup -REENC=$CRYPTSETUP_PATH/cryptsetup-reencrypt -FAST_PBKDF="--pbkdf-force-iterations 1000" +REENC_BIN=$CRYPTSETUP +REENC="$REENC_BIN reencrypt" +FAST_PBKDF="--pbkdf-force-iterations 1000 --pbkdf pbkdf2" + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs DEV_NAME=reenc9768 DEV_NAME2=reenc1273 IMG=reenc-data IMG_HDR=$IMG.hdr +HEADER_LUKS2_PV=blkid-luks2-pv.img ORIG_IMG=reenc-data-orig +DEV_LINK="reenc-test-link" KEY1=key1 PWD1="93R4P4pIqAH8" PWD2="1cND4319812f" @@ -17,10 +23,16 @@ PWD3="1-9Qu5Ejfnqv" MNT_DIR=./mnt_luks START_DIR=$(pwd) +FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) + +function fips_mode() +{ + [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] +} function del_scsi_device() { - rmmod scsi_debug 2>/dev/null + rmmod scsi_debug >/dev/null 2>&1 sleep 2 } @@ -29,7 +41,7 @@ function remove_mapping() [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 - rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1 + rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $HEADER_LUKS2_PV $DEV_LINK >/dev/null 2>&1 umount $MNT_DIR > /dev/null 2>&1 rmdir $MNT_DIR > /dev/null 2>&1 LOOPDEV1="" @@ -52,17 +64,33 @@ function skip() exit 77 } +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + function add_scsi_device() { del_scsi_device - modprobe scsi_debug $@ delay=0 - if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 - fi - - sleep 2 - SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) - [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." + if [ -d /sys/module/scsi_debug ] ; then + echo "Cannot use scsi_debug module (in use or compiled-in), test skipped." + exit 77 + fi + modprobe scsi_debug $@ delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + echo "This kernel seems to not support proper scsi_debug module, test skipped." + exit 77 + fi + + sleep 2 + SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." } function open_crypt() # $1 pwd, $2 hdr @@ -211,9 +239,21 @@ function test_logging() { echo } +function check_blkid() { + xz -dkf $HEADER_LUKS2_PV.xz + if ! $($CRYPTSETUP --version | grep -q "BLKID"); then + HAVE_BLKID=0 + elif $(blkid -p -n crypto_LUKS $HEADER_LUKS2_PV >/dev/null 2>&1); then + HAVE_BLKID=1 + else + HAVE_BLKID=0 + fi +} + [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." -[ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped." -which wipefs >/dev/null 2>&1 || skip "Cannot find wipefs, test skipped." +[ ! -x "$REENC_BIN" ] && skip "Cannot find $REENC_BIN, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run +command -v wipefs >/dev/null || skip "Cannot find wipefs, test skipped." # REENCRYPTION tests @@ -228,17 +268,17 @@ prepare 8192 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 -s 128 -c aes-cbc-plain $FAST_PBKDF --align-payload 4096 $LOOPDEV1 || fail wipe $PWD1 check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF || fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q -s 256 $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q -s 256 $FAST_PBKDF || fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q -s 256 -c aes-xts-plain64 -h sha256 $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q -s 256 -c aes-xts-plain64 -h sha256 $FAST_PBKDF || fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q --use-directio $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q --use-directio $FAST_PBKDF || fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q --master-key-file /dev/urandom $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q --volume-key-file /dev/urandom $FAST_PBKDF || fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q -s 512 --master-key-file /dev/urandom $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q -s 512 --volume-key-file /dev/urandom $FAST_PBKDF || fail check_hash $PWD1 $HASH1 $CRYPTSETUP --type luks1 luksDump $LOOPDEV1 > /dev/null || fail @@ -264,10 +304,24 @@ $REENC $LOOPDEV1 -d $KEY1 $FAST_PBKDF -q || fail # FIXME echo $PWD1 | $REENC ... echo "[4] Encryption of not yet encrypted device" +# Encrypt without size reduction must not allow header device same as data device +wipe_dev $LOOPDEV1 +echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $LOOPDEV1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail +ln -s $LOOPDEV1 $DEV_LINK || fail +echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail +rm -f $DEV_LINK || fail +echo $PWD1 | $REENC $IMG --type luks1 --new --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail +ln -s $IMG $DEV_LINK || fail +echo $PWD1 | $REENC $IMG --type luks1 --new --header $DEV_LINK -q $FAST_PBKDF_ARGON 2>/dev/null && fail +$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail + +if [ ! fips_mode ]; then # well, movin' zeroes :-) OFFSET=2048 SIZE=$(blockdev --getsz $LOOPDEV1) -wipe_dev $LOOPDEV1 dmsetup create $DEV_NAME2 --table "0 $(($SIZE - $OFFSET)) linear $LOOPDEV1 0" || fail check_hash_dev /dev/mapper/$DEV_NAME2 $HASH3 dmsetup remove --retry $DEV_NAME2 || fail @@ -290,6 +344,7 @@ OFFSET=4096 echo fake | $REENC $LOOPDEV1 -d $KEY1 --new --type luks1 --reduce-device-size "$OFFSET"S -q $FAST_PBKDF || fail $CRYPTSETUP open --test-passphrase $LOOPDEV1 -d $KEY1 || fail wipe_dev $LOOPDEV1 +fi echo "[5] Reencryption using specific keyslot" echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF $LOOPDEV1 || fail @@ -334,21 +389,21 @@ simple_scsi_reenc "[4096/512 sector]" echo "[OK]" echo "[8] Header only reencryption (hash and iteration time)" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 --hash sha1 $FAST_PBKDF $LOOPDEV1 || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 --hash sha512 $FAST_PBKDF $LOOPDEV1 || fail wipe $PWD1 check_hash $PWD1 $HASH1 echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key || fail check_hash $PWD1 $HASH1 echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --pbkdf-force-iterations 999 2>/dev/null && fail check_hash $PWD1 $HASH1 -echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha256 --pbkdf-force-iterations 1001 +echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha256 --pbkdf-force-iterations 1001 || fail check_hash $PWD1 $HASH1 [ "$($CRYPTSETUP luksDump $LOOPDEV1 | grep -A1 -m1 "Key Slot 0" | grep Iterations: | sed -e 's/[[:space:]]\+Iterations:\ \+//g')" -eq 1001 ] || fail [ "$($CRYPTSETUP luksDump $LOOPDEV1 | grep -m1 "Hash spec:" | cut -f2)" = "sha256" ] || fail -echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha512 $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha512 $FAST_PBKDF || fail check_hash $PWD1 $HASH1 [ "$($CRYPTSETUP luksDump $LOOPDEV1 | grep -A1 -m1 "Key Slot 0" | grep Iterations: | sed -e 's/[[:space:]]\+Iterations:\ \+//g')" -eq 1000 ] || fail -echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key $FAST_PBKDF +echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key $FAST_PBKDF || fail check_hash $PWD1 $HASH1 $CRYPTSETUP --type luks1 luksDump $LOOPDEV1 > /dev/null || fail @@ -363,6 +418,7 @@ add_scsi_device sector_size=512 dev_size_mb=32 physblk_exp=3 test_logging "[4096/512 sector]" || fail test_logging_tmpfs || fail +if [ ! fips_mode ]; then echo "[10] Removal of encryption" prepare 8192 echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF $LOOPDEV1 || fail @@ -382,9 +438,9 @@ prepare 8192 check_hash_dev $IMG $HASH4 echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR --new --type luks1 check_hash $PWD1 $HASH4 $IMG_HDR -echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR || fail check_hash $PWD1 $HASH4 $IMG_HDR -echo $PWD1 | $REENC $LOOPDEV1 -q --header $IMG_HDR --decrypt +echo $PWD1 | $REENC $LOOPDEV1 -q --header $IMG_HDR --decrypt || fail check_hash_dev $IMG $HASH4 # existing header of zero size cat /dev/null >$IMG_HDR @@ -393,5 +449,41 @@ check_hash $PWD1 $HASH4 $IMG_HDR $CRYPTSETUP isLuks $LOOPDEV1 && fail $CRYPTSETUP isLuks $IMG_HDR || fail +echo "[12] Prevent nested encryption" +prepare 8192 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF $LOOPDEV1 || fail + +#data device is already LUKS device (prevent nested encryption) +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks1 --reduce-device-size 1024S 2>/dev/null && fail +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks1 --header $IMG_HDR 2>/dev/null && fail +test -f $IMG_HDR && fail +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks2 --reduce-device-size 2048S 2>/dev/null && fail +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks2 --header $IMG_HDR 2>/dev/null && fail +test -f $IMG_HDR && fail + +wipe_dev $LOOPDEV1 +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 --header $IMG_HDR $FAST_PBKDF $LOOPDEV1 || fail + +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks1 --header $IMG_HDR 2>/dev/null && fail +echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --new --type luks2 --header $IMG_HDR 2>/dev/null && fail + +check_blkid +if [ "$HAVE_BLKID" -gt 0 ]; then + echo "[13] Prevent nested encryption of broken LUKS device" + rm -f $IMG_HDR + wipe_dev $LOOPDEV1 + xz -dkf $HEADER_LUKS2_PV.xz + # broken header + echo $PWD1 | $REENC --header $HEADER_LUKS2_PV $LOOPDEV1 -q $FAST_PBKDF --new --type luks1 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken device + echo $PWD1 | $REENC $HEADER_LUKS2_PV -q $FAST_PBKDF --new --type luks1 --reduce-device-size 1024S 2>/dev/null && fail + $CRYPTSETUP isLuks $HEADER_LUKS2_PV && fail + # broken data device only + echo $PWD1 | $REENC --header $IMG_HDR $HEADER_LUKS2_PV -q $FAST_PBKDF --new --type luks1 2>/dev/null && fail + test -f $IMG_HDR && fail +fi +fi # if [ ! fips_mode ] + remove_mapping exit 0 diff --git a/tests/reencryption-compat-test2 b/tests/reencryption-compat-test2 deleted file mode 100755 index 812788a..0000000 --- a/tests/reencryption-compat-test2 +++ /dev/null @@ -1,473 +0,0 @@ -#!/bin/bash - -[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".." -CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup -REENC=$CRYPTSETUP_PATH/cryptsetup-reencrypt -FAST_PBKDF_ARGON="--pbkdf-force-iterations 4 --pbkdf-memory 32 --pbkdf-parallel 1" -FAST_PBKDF_PBKDF2="--pbkdf-force-iterations 1000 --pbkdf pbkdf2" -DEFAULT_ARGON="argon2i" - -DEV_NAME=reenc9768 -DEV_NAME2=reenc1273 -IMG=reenc-data -IMG_HDR=$IMG.hdr -ORIG_IMG=reenc-data-orig -KEY1=key1 -PWD1="93R4P4pIqAH8" -PWD2="1cND4319812f" -PWD3="1-9Qu5Ejfnqv" - -MNT_DIR=./mnt_luks -START_DIR=$(pwd) -[ -f /etc/system-fips ] && FIPS_MODE=$(cat /proc/sys/crypto/fips_enabled 2>/dev/null) - -function fips_mode() -{ - [ -n "$FIPS_MODE" ] && [ "$FIPS_MODE" -gt 0 ] -} - -function dm_crypt_features() -{ - local VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv) - [ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version." - - local VER_MAJ=$(echo $VER_STR | cut -f 1 -d.) - local VER_MIN=$(echo $VER_STR | cut -f 2 -d.) - - [ $VER_MAJ -lt 1 ] && return - [ $VER_MAJ -eq 1 -a $VER_MIN -lt 11 ] && return - ALLOW_DISCARDS=--allow-discards - [ $VER_MAJ -eq 1 -a $VER_MIN -lt 14 ] && return - PERF_CPU=--perf-same_cpu_crypt -} - -function del_scsi_device() -{ - rmmod scsi_debug 2>/dev/null - sleep 2 -} - -function remove_mapping() -{ - [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 - [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME - rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1 - umount $MNT_DIR > /dev/null 2>&1 - rmdir $MNT_DIR > /dev/null 2>&1 - del_scsi_device -} - -function fail() -{ - [ -n "$1" ] && echo "$1" - echo "FAILED backtrace:" - while caller $frame; do ((frame++)); done - cd $START_DIR - remove_mapping - exit 2 -} - -function skip() -{ - [ -n "$1" ] && echo "$1" - exit 77 -} - -function add_scsi_device() { - del_scsi_device - modprobe scsi_debug $@ delay=0 - if [ $? -ne 0 ] ; then - echo "This kernel seems to not support proper scsi_debug module, test skipped." - exit 77 - fi - - sleep 2 - SCSI_DEV="/dev/"$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) - [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." -} - -function open_crypt() # $1 pwd, $2 hdr -{ - if [ -n "$2" ] ; then - echo "$1" | $CRYPTSETUP luksOpen $IMG $DEV_NAME --header $2 || fail - elif [ -n "$1" ] ; then - echo "$1" | $CRYPTSETUP luksOpen $IMG $DEV_NAME || fail - else - $CRYPTSETUP luksOpen -d $KEY1 $IMG $DEV_NAME || fail - fi -} - -function wipe_dev() # $1 dev -{ - dd if=/dev/zero of=$1 bs=256k conv=notrunc >/dev/null 2>&1 -} - -function wipe() # $1 pass -{ - open_crypt $1 - wipe_dev /dev/mapper/$DEV_NAME - udevadm settle >/dev/null 2>&1 - $CRYPTSETUP luksClose $DEV_NAME || fail -} - -function prepare() # $1 dev1_siz -{ - remove_mapping - - dd if=/dev/zero of=$IMG bs=1k count=$1 >/dev/null 2>&1 - - if [ ! -e $KEY1 ]; then - dd if=/dev/urandom of=$KEY1 count=1 bs=32 >/dev/null 2>&1 - fi -} - -function check_hash_dev() # $1 dev, $2 hash, $3 size -{ - if [ -n "$3" ]; then - HASH=$(head -c $3 $1 | sha256sum | cut -d' ' -f 1) - else - HASH=$(sha256sum $1 | cut -d' ' -f 1) - fi - [ $HASH != "$2" ] && fail "HASH differs ($HASH)" -} - -function check_hash() # $1 pwd, $2 hash, $3 hdr -{ - open_crypt $1 $3 - check_hash_dev /dev/mapper/$DEV_NAME $2 - $CRYPTSETUP remove $DEV_NAME || fail -} - -function backup_orig() -{ - sync - cp $IMG $ORIG_IMG -} - -function rollback() -{ - sync - cp $ORIG_IMG $IMG -} - -function check_slot() #space separated list of active key slots -{ - local _out=$($CRYPTSETUP luksDump $IMG | grep -e ": luks2" | sed -e 's/[[:space:]]*\([0-9]\+\):.*/\1/g') - - local _req - local _hdr - local _j - - for _i in $*; do - _j=$((_i)) - _req="$_req $_j" - done - - for _i in $_out; do - _j=$((_i)) - _hdr="$_hdr $_j" - done - - test "$_req" = "$_hdr" -} - -function simple_scsi_reenc() -{ - echo -n "$1" - echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_ARGON $SCSI_DEV || fail - - echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail - HASH=$(sha256sum /dev/mapper/$DEV_NAME | cut -d' ' -f 1) - $CRYPTSETUP luksClose $DEV_NAME || fail - - echo $PWD1 | $REENC -q $FAST_PBKDF_ARGON $SCSI_DEV || fail - - echo $PWD1 | $CRYPTSETUP luksOpen $SCSI_DEV $DEV_NAME || fail - check_hash_dev /dev/mapper/$DEV_NAME $HASH - $CRYPTSETUP luksClose $DEV_NAME || fail -} - -function mount_and_test() { - test -d $MNT_DIR || mkdir -p $MNT_DIR - mount $@ $MNT_DIR 2>/dev/null || { - echo -n "failed to mount [SKIP]" - return 0 - } - rm $MNT_DIR/* 2>/dev/null - cd $MNT_DIR - - if [ "${REENC:0:1}" != "/" ] ; then - MNT_REENC=$START_DIR/$REENC - else - MNT_REENC=$REENC - fi - echo $PWD2 | $MNT_REENC $START_DIR/$IMG -q --use-fsync --use-directio --write-log $FAST_PBKDF_ARGON || return 1 - cd $START_DIR - umount $MNT_DIR - echo -n [OK] -} - -function test_logging_tmpfs() { - echo -n "[tmpfs]" - mount_and_test -t tmpfs none -o size=$[25*1024*1024] || return 1 - echo -} - -function test_logging() { - echo -n "$1:" - for img in $(ls img_fs*img.xz) ; do - wipefs -a $SCSI_DEV > /dev/null - echo -n "[${img%.img.xz}]" - xz -d -c $img | dd of=$SCSI_DEV bs=4k >/dev/null 2>&1 - mount_and_test $SCSI_DEV || return 1 - done - echo -} - -[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." -[ ! -x "$REENC" ] && skip "Cannot find $REENC, test skipped." -which wipefs >/dev/null || skip "Cannot find wipefs, test skipped." -fips_mode && skip "This test cannot be run in FIPS mode." - -# REENCRYPTION tests - -HASH1=b69dae56a14d1a8314ed40664c4033ea0a550eea2673e04df42a66ac6b9faf2c -HASH4=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74 -HASH5=bb9f8df61474d25e71fa00722318cd387396ca1736605e1248821cc0de3d3af8 -HASH6=4d9cbaf3aa0935a8c113f139691b3daf9c94c8d6c278aedc8eec66a4b9f6c8ae -HASH7=5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef - -echo "[1] Reencryption" -prepare 8192 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 -c aes-cbc-plain $FAST_PBKDF_ARGON --offset 8192 $IMG || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q -s 256 $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q -s 256 -c aes-xts-plain64 -h sha256 $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --use-directio $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --master-key-file /dev/urandom $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q -s 512 --master-key-file /dev/urandom $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -s 128 --luks2-metadata-size 128k -c aes-cbc-plain $FAST_PBKDF_ARGON --offset 8192 $IMG > /dev/null || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON > /dev/null || fail -check_hash $PWD1 $HASH5 -MDA_SIZE=$($CRYPTSETUP luksDump $IMG | grep "Metadata area: " | cut -f 3 -d ' ') -test "$MDA_SIZE" -eq 131072 || fail "Unexpected Metadata area size $MDA_SIZE" - -echo "[2] Reencryption with data shift" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -c aes-cbc-essiv:sha256 -s 128 $FAST_PBKDF_ARGON --offset 8192 $IMG || fail -wipe $PWD1 -echo $PWD1 | $REENC $IMG -q -s 256 --reduce-device-size 1024S $FAST_PBKDF_ARGON || fail -check_hash $PWD1 $HASH6 -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON || fail -check_hash $PWD1 $HASH6 -$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail - -echo "[3] Reencryption with keyfile" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -d $KEY1 -c aes-cbc-essiv:sha256 -s 128 $FAST_PBKDF_ARGON --offset 8192 $IMG || fail -wipe -check_hash "" $HASH5 -echo $PWD1 | $CRYPTSETUP -q luksAddKey -d $KEY1 $IMG $FAST_PBKDF_ARGON || fail -$REENC $IMG -d $KEY1 $FAST_PBKDF_ARGON -q 2>/dev/null && fail -$REENC $IMG -d $KEY1 -S 0 $FAST_PBKDF_ARGON -q || fail -check_hash "" $HASH5 -check_slot 0 || fail "Only keyslot 0 expected to be enabled" -$REENC $IMG -d $KEY1 $FAST_PBKDF_ARGON -q || fail -$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail -# FIXME echo $PWD1 | $REENC ... - -echo "[4] Encryption of not yet encrypted device" -# well, movin' zeroes :-) -OFFSET=8192 # default LUKS2 header size -prepare 8192 -check_hash_dev $IMG $HASH4 -echo $PWD1 | $REENC --type luks2 $IMG -c aes-cbc-essiv:sha256 -s 128 --new --reduce-device-size "$OFFSET"S -q $FAST_PBKDF_ARGON || fail -check_hash $PWD1 $HASH5 -$CRYPTSETUP luksDump $IMG | grep -q "luks2" > /dev/null || fail -# 64MiB + 1 KiB -prepare 65537 -OFFSET=131072 -check_hash_dev $IMG $HASH7 1024 -echo $PWD1 | $REENC --type luks2 $IMG -c aes-cbc-essiv:sha256 -s 128 --new --reduce-device-size "$OFFSET"S -q $FAST_PBKDF_ARGON || fail -check_hash $PWD1 $HASH7 -$CRYPTSETUP --type luks2 luksDump $IMG > /dev/null || fail -prepare 8192 - -echo "[5] Reencryption using specific keyslot" -echo $PWD2 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 1 $IMG || fail -echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 2 $IMG || fail -echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 3 $IMG || fail -echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 4 $IMG || fail -echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 5 $IMG || fail -echo -e "$PWD2\n$PWD2" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 6 $IMG || fail -echo -e "$PWD2\n$PWD3" | $CRYPTSETUP -q luksAddKey $FAST_PBKDF_ARGON -S 22 $IMG || fail -backup_orig -echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 0 -q $IMG || fail -check_slot 0 || fail "Only keyslot 0 expected to be enabled" -wipe $PWD2 -rollback -echo $PWD1 | $REENC $FAST_PBKDF_ARGON -S 1 -q $IMG || fail -check_slot 1 || fail "Only keyslot 1 expected to be enabled" -wipe $PWD1 -rollback -echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 6 -q $IMG || fail -check_slot 6 || fail "Only keyslot 6 expected to be enabled" -wipe $PWD2 -rollback -echo $PWD3 | $REENC $FAST_PBKDF_ARGON -S 22 -q $IMG || fail -check_slot 22 || fail "Only keyslot 22 expected to be enabled" -wipe $PWD3 -rollback - -echo "[6] Reencryption using all active keyslots" -echo -e "$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD1\n$PWD2\n$PWD3" | $REENC -q $IMG $FAST_PBKDF_ARGON || fail -check_slot 0 1 2 3 4 5 6 22 || fail "All keyslots expected to be enabled" - -echo "[7] Reencryption of block devices with different block size" -add_scsi_device sector_size=512 dev_size_mb=32 -simple_scsi_reenc "[512 sector]" -add_scsi_device sector_size=4096 dev_size_mb=32 -simple_scsi_reenc "[4096 sector]" -add_scsi_device sector_size=512 physblk_exp=3 dev_size_mb=32 -simple_scsi_reenc "[4096/512 sector]" -echo "[OK]" - -echo "[8] Header only reencryption (hash and iteration time)" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --keep-key || fail -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 999 2>/dev/null && fail -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf-force-iterations 3 2>/dev/null && fail -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf-force-iterations 4 --pbkdf-memory 31 2>/dev/null && fail -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 1000 --hash sha512 -check_hash $PWD1 $HASH5 -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep PBKDF: | sed -e 's/[[:space:]]\+PBKDF:\ \+//g')" = "pbkdf2" ] || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep Hash: | sed -e 's/[[:space:]]\+Hash:\ \+//g')" = "sha512" ] || fail -echo $PWD1 | $REENC $IMG -q --keep-key $FAST_PBKDF_ARGON -check_hash $PWD1 $HASH5 -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep PBKDF: | sed -e 's/[[:space:]]\+PBKDF:\ \+//g')" = $DEFAULT_ARGON ] || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep "Time cost" | sed -e 's/[[:space:]]\+Time\ cost:\ \+//g')" -eq 4 ] || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep Memory | sed -e 's/[[[:space:]]\+Memory:\ \+//g')" -eq 32 ] || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A8 -m1 "0: luks2" | grep Threads | sed -e 's/[[[:space:]]\+Threads:\ \+//g')" -eq 1 ] || fail -echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey -S21 $FAST_PBKDF_ARGON $IMG || fail -echo $PWD2 | $REENC -S21 -q --keep-key --pbkdf pbkdf2 --pbkdf-force-iterations 1000 $IMG || fail -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 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 -add_scsi_device sector_size=4096 dev_size_mb=32 -test_logging "[4096 sector]" || fail -add_scsi_device sector_size=512 dev_size_mb=32 physblk_exp=3 -test_logging "[4096/512 sector]" || fail -test_logging_tmpfs || fail - -echo "[10] Removal of encryption" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --decrypt || fail -check_hash_dev $IMG $HASH4 - -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $REENC $IMG -q --decrypt || fail -check_hash_dev $IMG $HASH4 - -echo "[11] Reencryption with tokens" -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo -e "$PWD1\n$PWD2" | $CRYPTSETUP -q luksAddKey -S23 $FAST_PBKDF_ARGON $IMG || fail -echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey -S1 $FAST_PBKDF_ARGON $IMG || fail -echo -e "$PWD1\n$PWD3" | $CRYPTSETUP -q luksAddKey -S3 $FAST_PBKDF_ARGON $IMG || fai -$CRYPTSETUP token add --key-description key-name0 --key-slot 23 --token-id 0 $IMG -$CRYPTSETUP token add --key-description key-name2 --key-slot 1 --token-id 2 $IMG -$CRYPTSETUP token add --key-description key-name31 --token-id 31 $IMG -echo $PWD1 | $CRYPTSETUP -q luksKillSlot $IMG 3 || fail -echo $PWD2 | $REENC $FAST_PBKDF_ARGON -S 23 -q $IMG || fail -$CRYPTSETUP luksDump $IMG | grep "0: luks2-keyring" >/dev/null || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A2 -m1 "0: luks2-keyring" | grep Keyslot: | sed -e 's/[[[:space:]]\+Keyslot:\ \+//g')" -eq 23 ] || fail -$CRYPTSETUP luksDump $IMG | grep "2: luks2-keyring" >/dev/null || fail -$CRYPTSETUP luksDump $IMG | grep "31: luks2-keyring" >/dev/null || fail -[ "$($CRYPTSETUP luksDump $IMG | grep -A2 -m1 "31: luks2-keyring" | grep Keyslot: | sed -e 's/[[[:space:]]\+Keyslot:\ \+//g')" -eq 23 ] || fail - -echo "[12] Reencryption with persistent flags" -dm_crypt_features -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -echo $PWD1 | $CRYPTSETUP open $IMG $DEV_NAME $ALLOW_DISCARDS $PERF_CPU --persistent || fail -$CRYPTSETUP close $DEV_NAME || fail -echo $PWD1 | $REENC $FAST_PBKDF_ARGON -q $IMG || fail -if [ -n "$PERF_CPU" ]; then - $CRYPTSETUP luksDump $IMG | grep -m1 Flags: | grep same-cpu-crypt > /dev/null || fail -fi -if [ -n "$ALLOW_DISCARDS" ]; then - $CRYPTSETUP luksDump $IMG | grep -m1 Flags: | grep allow-discards > /dev/null || fail -fi - -echo "[13] Detached header - adding encryption/reencryption/decryption" -prepare 8192 -check_hash_dev $IMG $HASH4 -echo $PWD1 | $REENC --type luks2 $IMG -q $FAST_PBKDF_ARGON --header $IMG_HDR --new -check_hash $PWD1 $HASH4 $IMG_HDR -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_ARGON --header $IMG_HDR -check_hash $PWD1 $HASH4 $IMG_HDR -echo $PWD1 | $REENC $IMG -q --header $IMG_HDR --decrypt -check_hash_dev $IMG $HASH4 -# existing header of zero size -cat /dev/null >$IMG_HDR -echo $PWD1 | $REENC --type luks2 $IMG -q $FAST_PBKDF_ARGON --header $IMG_HDR --new -check_hash $PWD1 $HASH4 $IMG_HDR -$CRYPTSETUP isLuks $IMG && fail -$CRYPTSETUP isLuks $IMG_HDR || fail -$CRYPTSETUP luksDump $IMG_HDR | grep -q "0: luks2" || fail - -echo "[14] Reencryption with unbound keyslot" -prepare 8192 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $IMG --offset 8192 || fail -echo $PWD2 | $CRYPTSETUP -q luksAddKey -S 3 --unbound --key-size 64 $FAST_PBKDF_ARGON $IMG || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail -echo $PWD2 | $REENC $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail -echo -e "$PWD1\n$PWD2" | $REENC $IMG -q $FAST_PBKDF_ARGON || fail -$CRYPTSETUP luksDump $IMG | grep -q "3: luks2 (unbound)" || fail - -echo "[15] Reencryption after conversion" -prepare 8192 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_PBKDF2 $IMG --offset 4096 || fail -wipe $PWD1 -check_hash $PWD1 $HASH1 -$CRYPTSETUP -q convert --type luks2 $IMG || fail -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_PBKDF2 || fail -check_hash $PWD1 $HASH1 -echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_PBKDF2 $IMG --offset 8192 || fail -wipe $PWD1 -check_hash $PWD1 $HASH5 -$CRYPTSETUP -q convert --type luks1 $IMG || fail -echo $PWD1 | $REENC $IMG -q $FAST_PBKDF_PBKDF2 || fail -check_hash $PWD1 $HASH5 - -remove_mapping -exit 0 diff --git a/tests/run-all-symbols b/tests/run-all-symbols new file mode 100755 index 0000000..775d5bb --- /dev/null +++ b/tests/run-all-symbols @@ -0,0 +1,21 @@ +#!/bin/bash + +DIR=../.libs +FILE=$DIR/libcryptsetup.so + +function fail() +{ + [ -n "$1" ] && echo "$1" + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + exit 77 +} + +test -d $DIR || fail "Directory $DIR is missing." +test -f $FILE || skip "WARNING: Shared $FILE is missing, test skipped." + +./all-symbols-test $FILE $@ diff --git a/tests/ssh-test-plugin b/tests/ssh-test-plugin new file mode 100755 index 0000000..5b3966e --- /dev/null +++ b/tests/ssh-test-plugin @@ -0,0 +1,204 @@ +#!/bin/bash + +[ -z "$CRYPTSETUP_PATH" ] && { + TOKEN_PATH="./fake_token_path.so" + [ ! -f $TOKEN_PATH ] && { echo "Please compile $TOKEN_PATH."; exit 77; } + export LD_PRELOAD=$TOKEN_PATH + CRYPTSETUP_PATH=".." +} +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +CRYPTSETUP_SSH=$CRYPTSETUP_PATH/cryptsetup-ssh +IMG="ssh_test.img" +MAP="sshtest" +USER="sshtest" +PASSWD="sshtest1" +PASSWD2="sshtest2" +SSH_OPTIONS="-o StrictHostKeyChecking=no" + +SSH_SERVER="localhost" +SSH_PATH="/home/$USER/keyfile" +SSH_KEY_PATH="$HOME/sshtest-key" + +FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" + +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_SSH_VALGRIND=../.libs/cryptsetup-ssh +CRYPTSETUP_LIB_VALGRIND=../.libs + +[ -z "$srcdir" ] && srcdir="." + +function remove_mapping() +{ + [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP + rm -f $IMG >/dev/null 2>&1 +} + +function remove_user() +{ + id -u $USER >/dev/null 2>&1 && userdel -r -f $USER >/dev/null 2>&1 + rm -f $SSH_KEY_PATH "$SSH_KEY_PATH.pub" >/dev/null 2>&1 +} + +function create_user() +{ + id -u $USER >/dev/null 2>&1 + [ $? -eq 0 ] && skip "User account $USER exists, aborting." + [ -f $SSH_KEY_PATH ] && skip "SSH key $SSH_KEY_PATH already exists, aborting." + + useradd -m $USER -p $(openssl passwd $PASSWD) || skip "Failed to add user for SSH plugin test." + + ssh-keygen -f $SSH_KEY_PATH -q -N "" >/dev/null 2>&1 + [ $? -ne 0 ] && remove_user && skip "Failed to create SSH key." +} + +function ssh_check() +{ + # try to use netcat to check port 22 + nc -zv $SSH_SERVER 22 >/dev/null 2>&1 || skip "SSH server does not seem to be running, skipping." +} + +function bin_check() +{ + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." +} + +function ssh_setup() +{ + # copy the ssh key + [ -d "/home/$USER/.ssh" ] || mkdir /home/$USER/.ssh + touch /home/$USER/.ssh/authorized_keys + + cat $SSH_KEY_PATH.pub >> /home/$USER/.ssh/authorized_keys + [ $? -ne 0 ] && remove_user && fail "Failed to copy SSH key." + + # make sure /home/sshtest/.ssh and /home/sshtest/.ssh/authorized_keys have correct permissions + chown -R $USER:$USER /home/$USER/.ssh + chmod 700 /home/$USER/.ssh + chmod 644 /home/$USER/.ssh/authorized_keys + + # try to ssh and also create keyfile + ssh -i $SSH_KEY_PATH $SSH_OPTIONS -o BatchMode=yes -n $USER@$SSH_SERVER "echo -n $PASSWD > $SSH_PATH" >/dev/null 2>&1 + [ $? -ne 0 ] && remove_user && fail "Failed to connect using SSH." +} + +function fail() +{ + echo "[FAILED]" + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + remove_mapping + remove_user + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + remove_mapping + exit 77 +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + [ ! -f $CRYPTSETUP_SSH_VALGRIND ] && fail "Unable to get location of cryptsetup-ssh executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" +} + +function valgrind_run_ssh() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_SSH_VALGRIND} "$@" +} + +format() +{ + dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1 + + echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-password -q + [ $? -ne 0 ] && fail "Format failed." + + echo -e "$PASSWD\n$PASSWD2" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG -q + [ $? -ne 0 ] && fail "Add key failed." +} + +check_dump() +{ + dump=$1 + keyslot=$2 + + token=$(echo "$dump" | grep Tokens -A 1 | tail -1 | cut -d: -f2 | tr -d "\t\n ") + [ "$token" = "ssh" ] || fail " token check from dump failed." + + server=$(echo "$dump" | grep ssh_server | cut -d: -f2 | tr -d "\t\n ") + [ "$server" = $SSH_SERVER ] || fail " server check from dump failed." + + user=$(echo "$dump" | grep ssh_user | cut -d: -f2 | tr -d "\t\n ") + [ "$user" = "$USER" ] || fail " user check from dump failed." + + path=$(echo "$dump" | grep ssh_path | cut -d: -f2 | tr -d "\t\n ") + [ "$path" = "$SSH_PATH" ] || fail " path check from dump failed." + + key_path=$(echo "$dump" | grep ssh_key_path | cut -d: -f2 | tr -d "\t\n ") + [ "$key_path" = "$SSH_KEY_PATH" ] || fail " key_path check from dump failed." + + keyslot_dump=$(echo "$dump" | grep Keyslot: | cut -d: -f2 | tr -d "\t\n ") + [ "$keyslot_dump" = "$keyslot" ] || fail " keyslot check from dump failed." +} + +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run && CRYPTSETUP_SSH=valgrind_run_ssh +[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." + +# Prevent running dangerous useradd operation by default +[ -z "$RUN_SSH_PLUGIN_TEST" ] && skip "WARNING: Variable RUN_SSH_PLUGIN_TEST must be defined, test skipped." + +bin_check nc +bin_check useradd +bin_check ssh +bin_check ssh-keygen +bin_check sshpass +bin_check openssl + +format + +echo -n "Adding SSH token: " + +ssh_check +create_user +ssh_setup + +$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH +[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG" + +out=$($CRYPTSETUP luksDump $IMG) +check_dump "$out" 0 +echo "[OK]" + +echo -n "Activating using SSH token: " + +$CRYPTSETUP luksOpen --token-only --disable-external-tokens -r $IMG $MAP && fail "Tokens should be disabled" +$CRYPTSETUP luksOpen -r $IMG $MAP -q >/dev/null 2>&1 <&- +[ $? -ne 0 ] && fail "Failed to open $IMG using SSH token" +echo "[OK]" + +# Remove the newly added token and test adding with --key-slot +$CRYPTSETUP token remove --token-id 0 $IMG || fail "Failed to remove token" + +echo -n "Adding SSH token with --key-slot: " + +$CRYPTSETUP_SSH add $IMG --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH --key-slot 1 +[ $? -ne 0 ] && fail "Failed to add SSH token to $IMG" + +out=$($CRYPTSETUP luksDump $IMG) +check_dump "$out" 1 +echo "[OK]" + +remove_mapping +remove_user diff --git a/tests/systemd-test-plugin b/tests/systemd-test-plugin new file mode 100755 index 0000000..5f37324 --- /dev/null +++ b/tests/systemd-test-plugin @@ -0,0 +1,150 @@ +#!/bin/bash + +CC="cc" + +PASSWD="tpm2_test" +PASSWD2="tpm2_test2" +FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" +IMG=systemd_token_test.img +MAP="systemd_tpm2_test" + +function bin_check() +{ + command -v $1 >/dev/null || skip "WARNING: test require $1 binary, test skipped." +} + +function cleanup() { + [ -S $SWTPM_STATE_DIR/ctrl.sock ] && { + # shutdown TPM via control socket + swtpm_ioctl -s --unix $SWTPM_STATE_DIR/ctrl.sock + sleep 1 + } + + # if graceful shutdown was successful, pidfile should be deleted + # if it is still present, we forcefully kill the process + [ -f "$SWTPM_PIDFILE" ] && { + kill -9 $(cat $SWTPM_PIDFILE) >/dev/null 2>&1 + } + + [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP + + rm -f $SWTPM_PIDFILE >/dev/null 2>&1 + rm -rf $SWTPM_STATE_DIR >/dev/null 2>&1 + rm -f $IMG >/dev/null 2>&1 +} + +function fail() +{ + echo "[FAILED]" + [ -n "$1" ] && echo "$1" + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + cleanup + exit 2 +} + +function skip() +{ + [ -n "$1" ] && echo "$1" + cleanup + exit 77 +} + +# Prevent downloading and compiling systemd by default +[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] && skip "WARNING: Variable RUN_SYSTEMD_PLUGIN_TEST must be defined, test skipped." + +[ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." +bin_check swtpm +bin_check swtpm_ioctl + +CRYPTENROLL_LD_PRELOAD="" + +# if CRYPTSETUP_PATH is defined, we run against installed binaries, +# otherwise we compile systemd tokens from source +[ -z "$CRYPTSETUP_PATH" ] && { + bin_check git + bin_check meson + bin_check ninja + bin_check pkgconf + + TOKEN_PATH=fake_token_path.so + [ -f $TOKEN_PATH ] || skip "Please compile $TOKEN_PATH." + INSTALL_PATH=$(pwd)/external-tokens/install + make -C .. install DESTDIR=$INSTALL_PATH + PC_FILE="$(find $INSTALL_PATH -name 'libcryptsetup.pc')" + sed -i "s/^prefix=/prefix=${INSTALL_PATH//\//\\\/}/g" "$PC_FILE" + export PKG_CONFIG_PATH=$(dirname $PC_FILE) + + # systemd build system misses libcryptsetup.h if it is installed in non-default path + export CFLAGS="${CFLAGS:-} $(pkgconf --cflags libcryptsetup)" + + SYSTEMD_PATH=$(pwd)/external-tokens/systemd + CRYPTSETUP_PATH=$(pwd)/.. + SYSTEMD_CRYPTENROLL=$SYSTEMD_PATH/build/systemd-cryptenroll + + mkdir -p $SYSTEMD_PATH + [ "$(ls -A $SYSTEMD_PATH)" ] || git clone --depth=1 https://github.com/systemd/systemd.git $SYSTEMD_PATH + cd $SYSTEMD_PATH + meson -D tpm2=true -D libcryptsetup=true -D libcryptsetup-plugins=true build/ || skip "Failed to configure systemd via meson, some dependencies are probably missing." + ninja -C build/ systemd-cryptenroll libcryptsetup-token-systemd-tpm2.so || skip "Failed to build systemd." + + cd $CRYPTSETUP_PATH/tests + cp $SYSTEMD_PATH/build/libcryptsetup-token-*.so ../.libs/ + cp $SYSTEMD_PATH/build/src/shared/*.so ../.libs/ + + export LD_PRELOAD="${LD_PRELOAD-}:$CRYPTSETUP_PATH/tests/$TOKEN_PATH" + CRYPTENROLL_LD_PRELOAD="$CRYPTSETUP_PATH/.libs/libcryptsetup.so" +} +CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." + +[ -z "$SYSTEMD_CRYPTENROLL" ] && { + bin_check systemd-cryptenroll + SYSTEMD_CRYPTENROLL="systemd-cryptenroll" +} + +[ -z "$TPM_PATH" ] && { + echo "Setting up virtual TPM using swtpm..." + SWTPM_PIDFILE=$(mktemp /tmp/systemd_swtpm_pid.XXXXXX) + SWTPM_STATE_DIR=$(mktemp -d /tmp/systemd_swtpm_state.XXXXXX) + modprobe tpm_vtpm_proxy || skip "Failed to load tpm_vtpm_proxy kernel module, required for emulated TPM." + SWTPM_LOG=$(swtpm chardev --vtpm-proxy --tpm2 --tpmstate dir=$SWTPM_STATE_DIR -d --pid file=$SWTPM_PIDFILE --ctrl type=unixio,path=$SWTPM_STATE_DIR/ctrl.sock) + TPM_PATH=$(echo $SWTPM_LOG | grep -Eo '/dev/tpm([0-9])+' | sed 's/tpm/tpmrm/') + [ -z "$TPM_PATH" ] && skip "No TPM_PATH set and swtpm failed, test skipped." + sleep 1 + echo "Virtual TPM set up at $TPM_PATH" +} + +FAKE_TPM_PATH="$(pwd)/fake_systemd_tpm_path.so" +[ -f $FAKE_TPM_PATH ] || skip "Please compile $FAKE_TPM_PATH." +export LD_PRELOAD="$LD_PRELOAD:$FAKE_TPM_PATH" + +export TPM_PATH=$TPM_PATH +echo "TPM path is $TPM_PATH" + +dd if=/dev/zero of=$IMG bs=1M count=32 >/dev/null 2>&1 +echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $IMG --force-password -q + +echo "Enrolling the device to TPM 2 using systemd-cryptenroll.." +LD_PRELOAD="$LD_PRELOAD:$CRYPTENROLL_LD_PRELOAD" PASSWORD="$PASSWD" $SYSTEMD_CRYPTENROLL $IMG --tpm2-device=$TPM_PATH >/dev/null 2>&1 + +$CRYPTSETUP luksDump $IMG | grep -q "tpm2-blob" || fail "Failed to dump $IMG using systemd_tpm2 token (no tpm2-blob in output)." +echo "Activating the device via TPM2 external token.." +$CRYPTSETUP open --token-only $IMG $MAP >/dev/null 2>&1 || fail "Failed to open $IMG using systemd_tpm2 token." +$CRYPTSETUP close $MAP >/dev/null 2>&1 || fail "Failed to close $MAP." + +echo "Adding passphrase via TPM2 token.." +echo $PASSWD2 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $IMG --force-password -q --token-only >/dev/null 2>&1 || fail "Failed to add passphrase by tpm2 token." +echo $PASSWD2 | $CRYPTSETUP open $IMG --test-passphrase --disable-external-tokens >/dev/null 2>&1 || fail "Failed to test passphrase added by tpm2 token." + +echo "Exporting and removing TPM2 token.." +EXPORTED_TOKEN=$($CRYPTSETUP token export $IMG --token-id 0) +$CRYPTSETUP token remove $IMG --token-id 0 +$CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 && fail "Activating without passphrase should fail after TPM2 token removal." + +echo "Re-importing TPM2 token.." +echo $EXPORTED_TOKEN | $CRYPTSETUP token import $IMG --token-id 0 || fail "Failed to re-import deleted token." +$CRYPTSETUP open $IMG --test-passphrase --token-only >/dev/null 2>&1 || fail "Failed to activate after re-importing deleted token." + +cleanup +exit 0 diff --git a/tests/tcrypt-compat-test b/tests/tcrypt-compat-test index e706427..c0fc50a 100755 --- a/tests/tcrypt-compat-test +++ b/tests/tcrypt-compat-test @@ -11,6 +11,9 @@ PASSWORD_HIDDEN="bbbbbbbbbbbb" PASSWORD_72C="aaaaaaaaaaaabbbbbbbbbbbbccccccccccccddddddddddddeeeeeeeeeeeeffffffffffff" PIM=1234 +CRYPTSETUP_VALGRIND=../.libs/cryptsetup +CRYPTSETUP_LIB_VALGRIND=../.libs + [ -z "$srcdir" ] && srcdir="." function remove_mapping() @@ -18,6 +21,7 @@ function remove_mapping() [ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP [ -b /dev/mapper/"$MAP"_1 ] && dmsetup remove --retry "$MAP"_1 [ -b /dev/mapper/"$MAP"_2 ] && dmsetup remove --retry "$MAP"_2 + rm -rf $TST_DIR } function fail() @@ -33,7 +37,7 @@ function fail() function skip() { [ -n "$1" ] && echo "$1" - echo "Test skipped." + remove_mapping exit 77 } @@ -62,9 +66,16 @@ function test_kdf() # hash fi } +function get_HASH_CIPHER() # filename +{ + # speed up the test by limiting options for hash and (first) cipher + HASH=$(echo $file | cut -d'-' -f3) + CIPHER=$(echo $file | cut -d'-' -f5) +} + function test_required() { - which lsblk >/dev/null 2>&1 || skip "WARNING: lsblk tool required." + command -v blkid >/dev/null || skip "blkid tool required, test skipped." echo "REQUIRED KDF TEST" test_kdf sha256 @@ -96,11 +107,27 @@ function test_required() test_one camellia xts 512 camellia test_one kuznyechik xts 512 kuznyechik - ls $TST_DIR/[tv]c* >/dev/null 2>&1 || skip "No remaining images." + ls $TST_DIR/[tv]c* >/dev/null 2>&1 || skip "No remaining images, test skipped." +} + +function valgrind_setup() +{ + command -v valgrind >/dev/null || fail "Cannot find valgrind." + [ ! -f $CRYPTSETUP_VALGRIND ] && fail "Unable to get location of cryptsetup executable." + export LD_LIBRARY_PATH="$CRYPTSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" +} + +function valgrind_run() +{ + INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}" ./valg.sh ${CRYPTSETUP_VALGRIND} "$@" } export LANG=C +[ ! -x "$CRYPTSETUP" ] && skip "Cannot find $CRYPTSETUP, test skipped." [ ! -d $TST_DIR ] && tar xJf $srcdir/tcrypt-images.tar.xz --no-same-owner + +[ -n "$VALG" ] && valgrind_setup && CRYPTSETUP=valgrind_run + test_required echo "HEADER CHECK" @@ -110,14 +137,31 @@ for file in $(ls $TST_DIR/[tv]c_* $TST_DIR/vcpim_* $TST_DIR/sys_[tv]c_*) ; do [[ $file =~ vcpim.* ]] && PIM_OPT="--veracrypt-pim $PIM" SYS_OPT="" [[ $file =~ sys_.* ]] && SYS_OPT="--tcrypt-system" - echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $SYS_OPT $PIM_OPT $file >/dev/null || fail + get_HASH_CIPHER $file + echo $PASSWORD | $CRYPTSETUP tcryptDump $SYS_OPT $PIM_OPT -h $HASH -c $CIPHER $file >/dev/null || fail + if [[ $file =~ .*-sha512-xts-aes$ ]] ; then + echo $PASSWORD | $CRYPTSETUP tcryptDump $SYS_OPT $PIM_OPT -h sha512 -c aes $file >/dev/null || fail + echo $PASSWORD | $CRYPTSETUP tcryptDump $SYS_OPT $PIM_OPT -h xxxx $file 2>/dev/null && fail + echo $PASSWORD | $CRYPTSETUP tcryptDump $SYS_OPT $PIM_OPT -h sha512 -c xxx $file 2>/dev/null && fail + fi + echo " [OK]" +done + +echo "HEADER CHECK (TCRYPT only)" +for file in $(ls $TST_DIR/vc_* $TST_DIR/vcpim_*) ; do + echo -n " $file" + PIM_OPT="" + [[ $file =~ vcpim.* ]] && PIM_OPT="--veracrypt-pim $PIM" + get_HASH_CIPHER $file + echo $PASSWORD | $CRYPTSETUP tcryptDump --disable-veracrypt $PIM_OPT -h $HASH -c $CIPHER $file >/dev/null 2>&1 && fail echo " [OK]" done echo "HEADER CHECK (HIDDEN)" for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do echo -n " $file (hidden)" - echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden --veracrypt $file >/dev/null || fail + get_HASH_CIPHER $file + echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden -h $HASH -c $CIPHER $file >/dev/null || fail echo " [OK]" done @@ -127,13 +171,15 @@ for file in $(ls $TST_DIR/[tv]ck_*) ; do PWD=$PASSWORD [[ $file =~ vck_1_nopw.* ]] && PWD="" [[ $file =~ vck_1_pw72.* ]] && PWD=$PASSWORD_72C - echo $PWD | $CRYPTSETUP tcryptDump --veracrypt -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 $file >/dev/null || fail + get_HASH_CIPHER $file + echo $PWD | $CRYPTSETUP tcryptDump -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 -h $HASH -c $CIPHER $file >/dev/null || fail echo " [OK]" done if [ $(id -u) != 0 ]; then echo "WARNING: You must be root to run activation part of test, test skipped." + remove_mapping exit 0 fi @@ -144,14 +190,15 @@ for file in $(ls $TST_DIR/[tv]c_* $TST_DIR/vcpim_* $TST_DIR/sys_[tv]c_*) ; do [[ $file =~ vcpim.* ]] && PIM_OPT="--veracrypt-pim $PIM" SYS_OPT="" [[ $file =~ sys_.* ]] && SYS_OPT="--tcrypt-system" - out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen --veracrypt $SYS_OPT $PIM_OPT -r $file $MAP 2>&1) + get_HASH_CIPHER $file + out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen $SYS_OPT $PIM_OPT -r -h $HASH -c $CIPHER $file $MAP 2>&1) ret=$? [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue [ $ret -ne 0 ] && fail $CRYPTSETUP status $MAP >/dev/null || fail $CRYPTSETUP status /dev/mapper/$MAP >/dev/null || fail - UUID=$(lsblk -n -o UUID /dev/mapper/$MAP) + UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) $CRYPTSETUP remove $MAP || fail [ "$UUID" != "DEAD-BABE" ] && fail "UUID check failed." echo " [OK]" @@ -160,13 +207,17 @@ done echo "ACTIVATION FS UUID (HIDDEN) CHECK" for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do echo -n " $file" - out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen --veracrypt -r $file $MAP --tcrypt-hidden 2>&1) + get_HASH_CIPHER $file + out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r -h $HASH -c $CIPHER $file $MAP --tcrypt-hidden 2>&1) ret=$? [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue [ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue [ $ret -ne 0 ] && fail - UUID=$(lsblk -n -o UUID /dev/mapper/$MAP) + UUID=$(blkid -p -o value -s UUID /dev/mapper/$MAP) $CRYPTSETUP remove $MAP || fail [ "$UUID" != "CAFE-BABE" ] && fail "UUID check failed." echo " [OK]" done + +remove_mapping +exit 0 diff --git a/tests/test_utils.c b/tests/test_utils.c index 9f070e9..97c62a0 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -1,8 +1,8 @@ /* * cryptsetup library API test utilities * - * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved. - * Copyright (C) 2009-2021 Milan Broz + * Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2023 Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <assert.h> #include <errno.h> #include <fcntl.h> #include <inttypes.h> @@ -41,6 +42,16 @@ #include "api_test.h" #include "libcryptsetup.h" +#ifndef LOOP_CONFIGURE +#define LOOP_CONFIGURE 0x4C0A +struct loop_config { + __u32 fd; + __u32 block_size; + struct loop_info64 info; + __u64 __reserved[8]; +}; +#endif + static char last_error[256]; static char global_log[4096]; static uint32_t t_dm_crypt_flags = 0; @@ -151,6 +162,20 @@ int t_device_size(const char *device, uint64_t *size) return r; } +int t_set_readahead(const char *device, unsigned value) +{ + int devfd, r = 0; + + devfd = open(device, O_RDONLY); + if(devfd == -1) + return -EINVAL; + + if (ioctl(devfd, BLKRASET, value) < 0) + r = -EINVAL; + close(devfd); + return r; +} + int fips_mode(void) { int fd; @@ -186,14 +211,151 @@ int create_dmdevice_over_loop(const char *dm_name, const uint64_t size) printf("No enough space on backing loop device\n."); return -2; } - snprintf(cmd, sizeof(cmd), - "dmsetup create %s --table \"0 %" PRIu64 " linear %s %" PRIu64 "\"", - dm_name, size, THE_LOOP_DEV, t_dev_offset); + r = snprintf(cmd, sizeof(cmd), + "dmsetup create %s --table \"0 %" PRIu64 " linear %s %" PRIu64 "\"", + dm_name, size, THE_LOOP_DEV, t_dev_offset); + if (r < 0 || (size_t)r >= sizeof(cmd)) + return -3; + if (!(r = _system(cmd, 1))) t_dev_offset += size; return r; } +__attribute__((format(printf, 3, 4))) +static int _snprintf(char **r_ptr, size_t *r_remains, const char *format, ...) +{ + int len, r = 0; + va_list argp; + + assert(r_remains); + assert(r_ptr); + + va_start(argp, format); + + len = vsnprintf(*r_ptr, *r_remains, format, argp); + if (len < 0 || (size_t)len >= *r_remains) { + r = -EINVAL; + } else { + *r_ptr += len; + *r_remains -= len; + } + + va_end(argp); + + return r; +} + +int dmdevice_error_io(const char *dm_name, + const char *dm_device, + const char *error_device, + uint64_t data_offset, + uint64_t offset, + uint64_t length, + error_io_info ei) +{ + char str[256], cmd[384]; + int r; + uint64_t dev_size; + size_t remains; + char *ptr; + + if (t_device_size(dm_device, &dev_size) < 0 || !length) + return -1; + + dev_size >>= TST_SECTOR_SHIFT; + + if (dev_size <= offset) + return -1; + + if (ei == ERR_REMOVE) { + r = snprintf(cmd, sizeof(cmd), + "dmsetup load %s --table \"0 %" PRIu64 " linear %s %" PRIu64 "\"", + dm_name, dev_size, THE_LOOP_DEV, data_offset); + if (r < 0 || (size_t)r >= sizeof(str)) + return -3; + + if ((r = _system(cmd, 1))) + return r; + + r = snprintf(cmd, sizeof(cmd), "dmsetup resume %s", dm_name); + if (r < 0 || (size_t)r >= sizeof(cmd)) + return -3; + + return _system(cmd, 1); + } + + if ((dev_size - offset) < length) { + printf("Not enough space on target device\n."); + return -2; + } + + remains = sizeof(str); + ptr = str; + + if (offset) { + r = _snprintf(&ptr, &remains, + "0 %" PRIu64 " linear %s %" PRIu64 "\n", + offset, THE_LOOP_DEV, data_offset); + if (r < 0) + return r; + } + r = _snprintf(&ptr, &remains, "%" PRIu64 " %" PRIu64 " delay ", + offset, length); + if (r < 0) + return r; + + if (ei == ERR_RW || ei == ERR_RD) { + r = _snprintf(&ptr, &remains, "%s 0 0", + error_device); + if (r < 0) + return r; + if (ei == ERR_RD) { + r = _snprintf(&ptr, &remains, " %s %" PRIu64 " 0", + THE_LOOP_DEV, data_offset + offset); + if (r < 0) + return r; + } + } else if (ei == ERR_WR) { + r = _snprintf(&ptr, &remains, "%s %" PRIu64 " 0 %s 0 0", + THE_LOOP_DEV, data_offset + offset, error_device); + if (r < 0) + return r; + } + + if (dev_size > (offset + length)) { + r = _snprintf(&ptr, &remains, + "\n%" PRIu64 " %" PRIu64 " linear %s %" PRIu64, + offset + length, dev_size - offset - length, THE_LOOP_DEV, + data_offset + offset + length); + if (r < 0) + return r; + } + + /* + * Hello darkness, my old friend... + * + * On few old distributions there's issue with + * processing multiline tables via dmsetup load --table. + * This workaround passes on all systems we run tests on. + */ + r = snprintf(cmd, sizeof(cmd), "dmsetup load %s <<EOF\n%s\nEOF", dm_name, str); + if (r < 0 || (size_t)r >= sizeof(cmd)) + return -3; + + if ((r = _system(cmd, 1))) + return r; + + r = snprintf(cmd, sizeof(cmd), "dmsetup resume %s", dm_name); + if (r < 0 || (size_t)r >= sizeof(cmd)) + return -3; + + if ((r = _system(cmd, 1))) + return r; + + return t_set_readahead(dm_device, 0); +} + // Get key from kernel dm mapping table using dm-ioctl int get_key_dm(const char *name, char *buffer, unsigned int buffer_size) { @@ -201,7 +363,6 @@ int get_key_dm(const char *name, char *buffer, unsigned int buffer_size) struct dm_info dmi; uint64_t start, length; char *target_type, *key, *params; - void *next = NULL; int r = -EINVAL; if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) @@ -215,7 +376,7 @@ int get_key_dm(const char *name, char *buffer, unsigned int buffer_size) if (!dmi.exists) goto out; - next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); + dm_get_next_target(dmt, NULL, &start, &length, &target_type, ¶ms); if (!target_type || strcmp(target_type, "crypt") != 0) goto out; @@ -273,7 +434,7 @@ int crypt_decode_key(char *key, const char *hex, unsigned int size) return 0; } -void global_log_callback(int level, const char *msg, void *usrptr) +void global_log_callback(int level, const char *msg, void *usrptr __attribute__((unused))) { size_t len; @@ -322,7 +483,7 @@ int _system(const char *command, int warn) return r; } -static int keyring_check(void) +static int _keyring_check(void) { #ifdef KERNEL_KEYRING return syscall(__NR_request_key, "logon", "dummy", NULL, 0) == -1l && errno != ENOSYS; @@ -377,12 +538,28 @@ static void t_dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj, t_dm_crypt_flags |= T_DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED; } - if (t_dm_satisfies_version(1, 18, 1, crypt_maj, crypt_min, crypt_patch) && keyring_check()) + if (t_dm_satisfies_version(1, 18, 1, crypt_maj, crypt_min, crypt_patch) && _keyring_check()) t_dm_crypt_flags |= T_DM_KERNEL_KEYRING_SUPPORTED; + + if (t_dm_satisfies_version(1, 17, 0, crypt_maj, crypt_min, crypt_patch)) { + t_dm_crypt_flags |= T_DM_SECTOR_SIZE_SUPPORTED; + t_dm_crypt_flags |= T_DM_CAPI_STRING_SUPPORTED; + } + + if (t_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch)) + t_dm_crypt_flags |= T_DM_BITLK_EBOIV_SUPPORTED; + + if (t_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch)) + t_dm_crypt_flags |= T_DM_BITLK_ELEPHANT_SUPPORTED; + + if (t_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch)) + t_dm_crypt_flags |= T_DM_CRYPT_NO_WORKQUEUE_SUPPORTED; } -static void t_dm_set_verity_compat(const char *dm_version, unsigned verity_maj, - unsigned verity_min, unsigned verity_patch) +static void t_dm_set_verity_compat(const char *dm_version __attribute__((unused)), + unsigned verity_maj, + unsigned verity_min, + unsigned verity_patch __attribute__((unused))) { if (verity_maj > 0) t_dm_crypt_flags |= T_DM_VERITY_SUPPORTED; @@ -398,13 +575,42 @@ static void t_dm_set_verity_compat(const char *dm_version, unsigned verity_maj, t_dm_crypt_flags |= T_DM_VERITY_ON_CORRUPTION_SUPPORTED; t_dm_crypt_flags |= T_DM_VERITY_FEC_SUPPORTED; } + + if (t_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch)) + t_dm_crypt_flags |= T_DM_VERITY_SIGNATURE_SUPPORTED; + + if (t_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch)) + t_dm_crypt_flags |= T_DM_VERITY_PANIC_CORRUPTION_SUPPORTED; + + if (t_dm_satisfies_version(1, 9, 0, verity_maj, verity_min, verity_patch)) + t_dm_crypt_flags |= T_DM_VERITY_TASKLETS_SUPPORTED; } -static void t_dm_set_integrity_compat(const char *dm_version, unsigned integrity_maj, - unsigned integrity_min, unsigned integrity_patch) +static void t_dm_set_integrity_compat(const char *dm_version __attribute__((unused)), + unsigned integrity_maj __attribute__((unused)), + unsigned integrity_min __attribute__((unused)), + unsigned integrity_patch __attribute__((unused))) { if (integrity_maj > 0) t_dm_crypt_flags |= T_DM_INTEGRITY_SUPPORTED; + + if (t_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_RECALC_SUPPORTED; + + if (t_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_BITMAP_SUPPORTED; + + if (t_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_FIX_PADDING_SUPPORTED; + + if (t_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_DISCARDS_SUPPORTED; + + if (t_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_FIX_HMAC_SUPPORTED; + + if (t_dm_satisfies_version(1, 8, 0, integrity_maj, integrity_min, integrity_patch)) + t_dm_crypt_flags |= T_DM_INTEGRITY_RESET_RECALC_SUPPORTED; } int t_dm_check_versions(void) @@ -442,7 +648,7 @@ int t_dm_check_versions(void) (unsigned)target->version[1], (unsigned)target->version[2]); } - target = (struct dm_versions *)((char *) target + target->next); + target = VOIDP_CAST(struct dm_versions *)((char *) target + target->next); } while (last_target != target); r = 0; @@ -469,6 +675,21 @@ int t_dm_crypt_discard_support(void) return t_dm_crypt_flags & T_DM_DISCARDS_SUPPORTED; } +int t_dm_integrity_resize_support(void) +{ + return t_dm_crypt_flags & T_DM_INTEGRITY_RESIZE_SUPPORTED; +} + +int t_dm_integrity_recalculate_support(void) +{ + return t_dm_crypt_flags & T_DM_INTEGRITY_RECALC_SUPPORTED; +} + +int t_dm_capi_string_supported(void) +{ + return t_dm_crypt_flags & T_DM_CAPI_STRING_SUPPORTED; +} + /* loop helpers */ #define LOOP_DEV_MAJOR 7 @@ -501,7 +722,7 @@ int loop_device(const char *loop) static char *crypt_loop_get_device_old(void) { - char dev[20]; + char dev[64]; int i, loop_fd; struct loop_info64 lo64 = {0}; @@ -552,9 +773,10 @@ static char *crypt_loop_get_device(void) int loop_attach(char **loop, const char *file, int offset, int autoclear, int *readonly) { - struct loop_info64 lo64 = {0}; + struct loop_config config = {0}; char *lo_file_name; int loop_fd = -1, file_fd = -1, r = 1; + int fallback = 0; *loop = NULL; @@ -566,6 +788,15 @@ int loop_attach(char **loop, const char *file, int offset, if (file_fd < 0) goto out; + config.fd = file_fd; + + lo_file_name = (char*)config.info.lo_file_name; + lo_file_name[LO_NAME_SIZE-1] = '\0'; + strncpy(lo_file_name, file, LO_NAME_SIZE-1); + config.info.lo_offset = offset; + if (autoclear) + config.info.lo_flags |= LO_FLAGS_AUTOCLEAR; + while (loop_fd < 0) { *loop = crypt_loop_get_device(); if (!*loop) @@ -574,8 +805,18 @@ int loop_attach(char **loop, const char *file, int offset, loop_fd = open(*loop, *readonly ? O_RDONLY : O_RDWR); if (loop_fd < 0) goto out; - - if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0) { + if (ioctl(loop_fd, LOOP_CONFIGURE, &config) < 0) { + if (errno == EINVAL || errno == ENOTTY) { + free(*loop); + *loop = NULL; + + close(loop_fd); + loop_fd = -1; + + /* kernel doesn't support LOOP_CONFIGURE */ + fallback = 1; + break; + } if (errno != EBUSY) goto out; free(*loop); @@ -586,23 +827,38 @@ int loop_attach(char **loop, const char *file, int offset, } } - lo_file_name = (char*)lo64.lo_file_name; - lo_file_name[LO_NAME_SIZE-1] = '\0'; - strncpy(lo_file_name, file, LO_NAME_SIZE-1); - lo64.lo_offset = offset; - if (autoclear) - lo64.lo_flags |= LO_FLAGS_AUTOCLEAR; + if (fallback) + { + while (loop_fd < 0) { + *loop = crypt_loop_get_device(); + if (!*loop) + goto out; - if (ioctl(loop_fd, LOOP_SET_STATUS64, &lo64) < 0) { - (void)ioctl(loop_fd, LOOP_CLR_FD, 0); - goto out; + loop_fd = open(*loop, *readonly ? O_RDONLY : O_RDWR); + if (loop_fd < 0) + goto out; + if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0) { + if (errno != EBUSY) + goto out; + free(*loop); + *loop = NULL; + + close(loop_fd); + loop_fd = -1; + } + } + + if (ioctl(loop_fd, LOOP_SET_STATUS64, &config.info) < 0) { + (void)ioctl(loop_fd, LOOP_CLR_FD, 0); + goto out; + } } /* Verify that autoclear is really set */ if (autoclear) { - memset(&lo64, 0, sizeof(lo64)); - if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 || - !(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) { + memset(&config.info, 0, sizeof(config.info)); + if (ioctl(loop_fd, LOOP_GET_STATUS64, &config.info) < 0 || + !(config.info.lo_flags & LO_FLAGS_AUTOCLEAR)) { (void)ioctl(loop_fd, LOOP_CLR_FD, 0); goto out; } @@ -635,3 +891,60 @@ int loop_detach(const char *loop) close(loop_fd); return r; } + +int t_get_devno(const char *name, dev_t *devno) +{ + char path[PATH_MAX]; + int r; + struct stat st; + + r = snprintf(path, sizeof(path), DMDIR "%s", name); + if (r < 0 || (size_t)r >= sizeof(path)) + return 1; + + if (stat(path, &st) || !S_ISBLK(st.st_mode)) + return 1; + + *devno = st.st_rdev; + + return 0; +} + +static int _read_uint64(const char *sysfs_path, uint64_t *value) +{ + char tmp[64] = {0}; + int fd, r; + + if ((fd = open(sysfs_path, O_RDONLY)) < 0) + return 0; + r = read(fd, tmp, sizeof(tmp)); + close(fd); + + if (r <= 0) + return 0; + + if (sscanf(tmp, "%" PRIu64, value) != 1) + return 0; + + return 1; +} + +static int _sysfs_get_uint64(int major, int minor, uint64_t *value, const char *attr) +{ + char path[PATH_MAX]; + + if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s", + major, minor, attr) < 0) + return 0; + + return _read_uint64(path, value); +} + +int t_device_size_by_devno(dev_t devno, uint64_t *retval) +{ + if (!_sysfs_get_uint64(major(devno), minor(devno), retval, "size")) + return 1; + + *retval *= 512; + return 0; +} diff --git a/tests/unit-utils-crypt.c b/tests/unit-utils-crypt.c new file mode 100644 index 0000000..4ab3c96 --- /dev/null +++ b/tests/unit-utils-crypt.c @@ -0,0 +1,259 @@ +/* + * cryptsetup crypto name and hex conversion helper test vectors + * + * Copyright (C) 2022-2023 Milan Broz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "utils_crypt.h" +#include "libcryptsetup.h" + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +/* + * Cryptsetup/dm-crypt algorithm naming conversion test + */ +struct mode_test_vector { + const char *input; + const char *cipher; + const char *mode; + int keys; +}; +static struct mode_test_vector mode_test_vectors[] = { + { "aes-xts-plain", "aes", "xts-plain", 1 }, + { "aes-xts-plain64", "aes", "xts-plain64", 1 }, + { "aes-cbc-plain", "aes", "cbc-plain", 1 }, + { "aes-cbc-plain64", "aes", "cbc-plain64", 1 }, + { "aes-cbc-essiv:sha256", "aes", "cbc-essiv:sha256", 1 }, + { "aes", "aes", "cbc-plain", 1 }, + { "twofish", "twofish", "cbc-plain", 1 }, + { "cipher_null", "cipher_null", "ecb", 0 }, + { "null", "cipher_null", "ecb", 0 }, + { "xchacha12,aes-adiantum-plain64", "xchacha12,aes", "adiantum-plain64", 1 }, + { "xchacha20,aes-adiantum-plain64", "xchacha20,aes", "adiantum-plain64", 1 }, + { "aes:64-cbc-lmk", "aes:64", "cbc-lmk", 64 }, + { "des3_ede-cbc-tcw", "des3_ede" ,"cbc-tcw", 1 }, + { "aes-lrw-benbi", "aes","lrw-benbi", 1 }, +}; + +static int test_parse_mode(void) +{ + char cipher[MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN]; + unsigned int i; + int keys; + + printf("MODECONV:"); + for (i = 0; i < ARRAY_SIZE(mode_test_vectors); i++) { + if (i && !(i % 8)) + printf("\n"); + keys = -1; + memset(cipher, 0, sizeof(cipher)); + memset(mode, 0, sizeof(mode)); + printf("[%s]", mode_test_vectors[i].input ?: "NULL"); + if (crypt_parse_name_and_mode(mode_test_vectors[i].input, cipher, &keys, mode) < 0 || + strcmp(mode_test_vectors[i].cipher, cipher) || + strcmp(mode_test_vectors[i].mode, mode) || + mode_test_vectors[i].keys != keys) { + printf("[FAILED (%s / %s / %i)]\n", cipher, mode, keys); + return EXIT_FAILURE; + } + } + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + +/* + * Cryptsetup/dm-crypt/dm-integrity algorithm naming conversion test + */ +struct integrity_test_vector { + bool int_mode; /* non-null if it is supported as integrity mode for LUKS2 */ + const char *input; + const char *integrity; + int key_size; +}; +static struct integrity_test_vector integrity_test_vectors[] = { + { true, "aead", "aead", 0 }, + { true, "poly1305", "poly1305", 0 }, + { true, "none", "none", 0 }, + { false, "crc32", "crc32", 0 }, + { true, "hmac-sha1", "hmac(sha1)", 20 }, + { true, "hmac-sha256", "hmac(sha256)", 32 }, + { true, "hmac-sha512", "hmac(sha512)", 64 }, + { true, "cmac-aes", "cmac(aes)", 16 }, + { false, "blake2b-256", "blake2b-256", 0 }, +}; + +static int test_parse_integrity_mode(void) +{ + char integrity[MAX_CIPHER_LEN]; + unsigned int i; + int key_size; + + printf("INTEGRITYCONV:"); + for (i = 0; i < ARRAY_SIZE(integrity_test_vectors); i++) { + memset(integrity, 0, sizeof(integrity)); + printf("[%s,%i]", integrity_test_vectors[i].input ?: "NULL", integrity_test_vectors[i].key_size); + if (crypt_parse_hash_integrity_mode(integrity_test_vectors[i].input, integrity) < 0 || + strcmp(integrity_test_vectors[i].integrity, integrity)) { + printf("[FAILED (%s)]\n", integrity); + return EXIT_FAILURE; + } + key_size = -1; + memset(integrity, 0, sizeof(integrity)); + if (integrity_test_vectors[i].int_mode && + (crypt_parse_integrity_mode(integrity_test_vectors[i].input, integrity, &key_size) < 0 || + strcmp(integrity_test_vectors[i].integrity, integrity) || + integrity_test_vectors[i].key_size != key_size)) { + printf("[FAILED (%s / %i)]\n", integrity, key_size); + return EXIT_FAILURE; + } + } + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + +/* + * Cryptsetup null cipher bypass algorithm name + */ +struct null_test_vector { + const char *cipher; + bool ok; +}; +static struct null_test_vector null_test_vectors[] = { + { "cipher_null-ecb", true }, + { "cipher_null", true }, + { "null", true }, + { "cipher-null", false }, + { "aes-ecb", false }, + { NULL, false }, +}; + +static int test_cipher_null(void) +{ + unsigned int i; + + printf("NULLCONV:"); + for (i = 0; i < ARRAY_SIZE(null_test_vectors); i++) { + printf("[%s]", null_test_vectors[i].cipher ?: "NULL"); + if (crypt_is_cipher_null(null_test_vectors[i].cipher) != + null_test_vectors[i].ok) { + printf("[FAILED]\n"); + return EXIT_FAILURE; + } + } + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + +struct hex_test_vector { + const char *hex; + const char *bytes; + ssize_t bytes_size; + bool ok; +}; +static struct hex_test_vector hex_test_vectors[] = { + { "0000000000000000", "\x00\x00\x00\x00\x00\x00\x00\x00", 8, true }, + { "abcdef0123456789", "\xab\xcd\xef\x01\x23\x45\x67\x89", 8, true }, + { "aBCDef0123456789", "\xab\xcd\xef\x01\x23\x45\x67\x89", 8, true }, + { "ff", "\xff", 1, true }, + { "f", NULL , 1, false }, + { "a-cde", NULL, 2, false }, + { "FAKE", NULL, 2, false }, + { "\x01\x02\xff", NULL, 3, false }, + { NULL, NULL, 1, false }, + { "fff", NULL, 2, false }, + { "fg", NULL, 1, false }, +}; + +/* + * Hexa conversion test (also should be constant time) + */ +static int test_hex_conversion(void) +{ + char *bytes, *hex; + ssize_t len; + unsigned int i; + + printf("HEXCONV:"); + for (i = 0; i < ARRAY_SIZE(hex_test_vectors); i++) { + bytes = NULL; + hex = NULL; + if (hex_test_vectors[i].hex && *hex_test_vectors[i].hex >= '0') + printf("[%s]", hex_test_vectors[i].hex); + else + printf("[INV:%i]", i); + len = crypt_hex_to_bytes(hex_test_vectors[i].hex, &bytes, 1); + if ((hex_test_vectors[i].ok && len != hex_test_vectors[i].bytes_size) || + (!hex_test_vectors[i].ok && len >= 0)) { + printf("[FAILED]\n"); + crypt_safe_free(bytes); + return EXIT_FAILURE; + } + crypt_safe_free(bytes); + hex = crypt_bytes_to_hex(hex_test_vectors[i].bytes_size, hex_test_vectors[i].bytes); + if ((hex_test_vectors[i].ok && strcasecmp(hex, hex_test_vectors[i].hex)) || + (!hex_test_vectors[i].ok && hex)) { + printf("[FAILED]\n"); + crypt_safe_free(hex); + return EXIT_FAILURE; + } + crypt_safe_free(hex); + } + printf("[OK]\n"); + + return EXIT_SUCCESS; +} + +static void __attribute__((noreturn)) exit_test(const char *msg, int r) +{ + if (msg) + printf("%s\n", msg); + exit(r); +} + +int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[]) +{ + setvbuf(stdout, NULL, _IONBF, 0); + +#ifndef NO_CRYPTSETUP_PATH + if (getenv("CRYPTSETUP_PATH")) { + printf("Cannot run this test with CRYPTSETUP_PATH set.\n"); + exit(77); + } +#endif + if (test_parse_mode()) + exit_test("Parse mode test failed.", EXIT_FAILURE); + + if (test_parse_integrity_mode()) + exit_test("Parse integrity mode test failed.", EXIT_FAILURE); + + if (test_cipher_null()) + exit_test("CIPHER null test failed.", EXIT_FAILURE); + + if (test_hex_conversion()) + exit_test("HEX conversion test failed.", EXIT_FAILURE); + + exit_test(NULL, EXIT_SUCCESS); +} diff --git a/tests/unit-utils-io.c b/tests/unit-utils-io.c index 8120842..3bfc762 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-2021 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2023 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 @@ -311,6 +311,12 @@ int main(int argc, char **argv) long ps; int r = EXIT_FAILURE; +#ifndef NO_CRYPTSETUP_PATH + if (getenv("CRYPTSETUP_PATH")) { + printf("Cannot run this test with CRYPTSETUP_PATH set.\n"); + exit(77); + } +#endif if (parse_input_params(argc, argv)) return r; diff --git a/tests/unit-wipe-test b/tests/unit-wipe-test new file mode 100755 index 0000000..4d0a078 --- /dev/null +++ b/tests/unit-wipe-test @@ -0,0 +1,170 @@ +#!/bin/bash + +WIPE_UNIT=./unit-wipe +FILE=./wipe_localfile +FILE_RAND=./wipe_random_localfile +MB_BYTES=$((1024*1024)) +DEVSIZEMB=8 +DEVSIZE=$((DEVSIZEMB*$MB_BYTES)) + +HASH_EMPTY=2daeb1f36095b44b318410b3f4e8b5d989dcc7bb023d1426c492dab0a3053e74 + +function cleanup() { + rm -f $FILE $FILE_RAND 2> /dev/null + sleep 1 + rmmod scsi_debug >/dev/null 2>&1 +} + +function fail() +{ + if [ -n "$1" ] ; then echo "FAIL $1" ; else echo "FAIL" ; fi + echo "FAILED backtrace:" + while caller $frame; do ((frame++)); done + cleanup + exit 100 +} + +function skip() +{ + echo "TEST SKIPPED: $1" + cleanup + exit 77 +} + +function add_device() +{ + rmmod scsi_debug >/dev/null 2>&1 + if [ -d /sys/module/scsi_debug ] ; then + skip "Cannot use scsi_debug module (in use or compiled-in)." + fi + modprobe scsi_debug dev_size_mb=$DEVSIZEMB num_tgts=1 delay=0 >/dev/null 2>&1 + if [ $? -ne 0 ] ; then + skip "This kernel seems to not support proper scsi_debug module." + fi + grep -q scsi_debug /sys/block/*/device/model || sleep 2 + DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /) + DEV="/dev/$DEV" + [ -b $DEV ] || fail "Cannot find $DEV." +} + +function check_hash() # $1 dev, $2 hash +{ + local HASH=$(sha256sum $1 | cut -d' ' -f 1) + [ $HASH == "$2" ] +} + +function init_hash_dd() # $1 dev, $dev orig +{ + dd if=/dev/urandom of=$2 bs=1M count=$DEVSIZEMB conv=notrunc 2> /dev/null + dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null + HASH_0=$(sha256sum $1 | cut -d' ' -f 1) + # second MB wiped + dd if=/dev/zero of=$1 bs=1M seek=1 count=1 conv=notrunc 2> /dev/null + HASH_1=$(sha256sum $1 | cut -d' ' -f 1) + # 4,5,6 MB wiped + dd if=/dev/zero of=$1 bs=1M seek=4 count=3 conv=notrunc 2> /dev/null + HASH_2=$(sha256sum $1 | cut -d' ' -f 1) + dd if=$2 of=$1 bs=1M conv=notrunc 2> /dev/null +} + +function add_file() +{ + dd if=/dev/zero of=$FILE bs=1M count=$DEVSIZEMB 2> /dev/null || fail + dd if=/dev/zero of=$FILE_RAND bs=1M count=$DEVSIZEMB 2> /dev/null || fail + check_hash $FILE $HASH_EMPTY || fail + check_hash $FILE_RAND $HASH_EMPTY || fail + dd if=$FILE of=/dev/null bs=4096 count=1 iflag=direct >/dev/null 2>&1 || FILE_NODIO=1 +} + +function test_wipe_full() # $1 dev, $2 block size, [$3 flags] +{ + # wipe random and back to zero + $WIPE_UNIT $1 random 0 $DEVSIZE $2 $3 || fail + check_hash $1 $HASH_EMPTY && fail "Failed random wipe" + $WIPE_UNIT $1 zero 0 $DEVSIZE $2 $3 || fail + check_hash $1 $HASH_EMPTY || fail "Failed zero wipe" +} + +# wipe MB blocks, with zero, random and special and back to original +function test_wipe_blocks() # $1 dev $2 block sizem [$3 flags] +{ + init_hash_dd $1 $FILE_RAND + check_hash $1 $HASH_0 || fail + + $WIPE_UNIT $1 zero $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_1 || fail + $WIPE_UNIT $1 random $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_1 && fail + $WIPE_UNIT $1 special $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_1 && fail + $WIPE_UNIT $1 zero $((1*$MB_BYTES)) $((1*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_1 || fail + + $WIPE_UNIT $1 zero $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_2 || fail + $WIPE_UNIT $1 random $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_2 && fail + $WIPE_UNIT $1 special $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_2 && fail + $WIPE_UNIT $1 zero $((4*$MB_BYTES)) $((3*$MB_BYTES)) $2 $3 || fail + check_hash $1 $HASH_2 || fail +} + +test -x $WIPE_UNIT || skip "Run \"make `basename $WIPE_UNIT`\" first" + +cleanup +add_file + +echo -n "[1] Wipe full file " +for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do + if [ -n "$FILE_NODIO" ]; then + echo -n [$bs/DIO N/A] + else + echo -n [$bs/DIO] + test_wipe_full $FILE $bs + fi + echo -n [$bs] + test_wipe_full $FILE $bs no-dio +done +echo "[OK]" + +echo -n "[2] Wipe blocks in file " +for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do + if [ -n "$FILE_NODIO" ]; then + echo -n [$bs/DIO N/A] + else + echo -n [$bs/DIO] + test_wipe_blocks $FILE $bs + fi + echo -n [$bs] + test_wipe_blocks $FILE $bs no-dio +done +echo "[OK]" + +[ $(id -u) -eq 0 ] || { + echo "WARNING: You must be root to run remaining tests." + cleanup + exit 0 +} + +add_device + +echo -n "[3] Wipe full block device " +for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do + echo -n [$bs/DIO] + test_wipe_full $DEV $bs + echo -n [$bs] + test_wipe_full $DEV $bs no-dio +done +echo "[OK]" + +echo -n "[4] Wipe blocks in block device " +for bs in 0 $MB_BYTES $((4*$MB_BYTES)); do + echo -n [$bs/DIO] + test_wipe_blocks $DEV $bs + echo -n [$bs] + test_wipe_blocks $DEV $bs no-dio +done +echo "[OK]" + +cleanup diff --git a/tests/unit-wipe.c b/tests/unit-wipe.c new file mode 100644 index 0000000..c3019c7 --- /dev/null +++ b/tests/unit-wipe.c @@ -0,0 +1,138 @@ +/* + * unit test helper for crypt_wipe API call + * + * Copyright (C) 2022-2023 Milan Broz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <sys/stat.h> + +#include "libcryptsetup.h" + +const char *test_file; +uint64_t test_offset, test_length, test_block; +uint32_t flags; +crypt_wipe_pattern pattern; + +static void usage(void) +{ + fprintf(stderr, "Use:\tunit-wipe file/device zero|random|special offset length bsize [no-dio].\n"); +} + +static bool parse_u64(const char *arg, uint64_t *u64) +{ + unsigned long long ull; + char *end; + + ull = strtoull(arg, &end, 10); + if (*end || !*arg || errno == ERANGE) + return false; + + if (ull % 512) + return false; + + *u64 = ull; + return true; +} + +static bool parse_input_params(int argc, char **argv) +{ + struct stat st; + + if (argc < 6 || argc > 7) { + usage(); + return false; + } + + if (stat(argv[1], &st)) { + fprintf(stderr, "File/device %s is missing?\n", argv[1]); + return false; + } + test_file = argv[1]; + + if (!strcmp(argv[2], "random")) + pattern = CRYPT_WIPE_RANDOM; + else if (!strcmp(argv[2], "zero")) + pattern = CRYPT_WIPE_ZERO; + else if (!strcmp(argv[2], "special")) + pattern = CRYPT_WIPE_SPECIAL; + else { + fprintf(stderr, "Wrong pattern specification.\n"); + return false; + } + + if (!parse_u64(argv[3], &test_offset)) { + fprintf(stderr, "Wrong offset specification.\n"); + return false; + } + + if (!parse_u64(argv[4], &test_length)) { + fprintf(stderr, "Wrong length specification.\n"); + return false; + } + + if (!parse_u64(argv[5], &test_block)) { + fprintf(stderr, "Wrong block length specification.\n"); + return false; + } + + if (argc > 6) { + if (!strcmp(argv[6], "no-dio")) + flags = CRYPT_WIPE_NO_DIRECT_IO; + else { + fprintf(stderr, "Wrong flags specification.\n"); + return false; + } + } + + return true; +} + +int main(int argc, char **argv) +{ + struct crypt_device *cd; + int r; + +#ifndef NO_CRYPTSETUP_PATH + if (getenv("CRYPTSETUP_PATH")) { + printf("Cannot run this test with CRYPTSETUP_PATH set.\n"); + exit(77); + } +#endif + + if (!parse_input_params(argc, argv)) + return EXIT_FAILURE; + + r = crypt_init(&cd, NULL); + if (r < 0) { + fprintf(stderr, "Context init failure %i.\n", r); + return EXIT_FAILURE; + } + + r = crypt_wipe(cd, test_file, pattern, test_offset, test_length, + test_block, flags, NULL, NULL); + crypt_free(cd); + + if (r) + fprintf(stderr, "Failure %i\n", r); + + return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/valg-api.sh b/tests/valg-api.sh index fcd59a8..4c6a600 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 +%H:%M:%S:%N)_${INFOSTRING}" +LOGFILE="--log-file=./valglog.$(date +%j:%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 888efcc..f3d4032 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 +%H:%M:%S:%N)_${INFOSTRING}" +LOGFILE="--log-file=./valglog.$(date +%j:%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 7f381e7..8a28a12 100755 --- a/tests/verity-compat-test +++ b/tests/verity-compat-test @@ -6,6 +6,7 @@ VERITYSETUP_VALGRIND=../.libs/veritysetup VERITYSETUP_LIB_VALGRIND=../.libs DEV_NAME=verity3273 +DEV_NAME2=verity3273x DEV_OUT="$DEV_NAME.out" IMG=verity-data IMG_HASH=verity-hash @@ -17,9 +18,10 @@ DEV_UUID=a60c98d2-ae9b-4865-bfcb-b4e3ace11033 function remove_mapping() { + [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 >/dev/null 2>&1 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME >/dev/null 2>&1 [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 - rm -f $IMG $IMG_HASH $DEV_OUT $FEC_DEV $IMG_TMP >/dev/null 2>&1 + rm -f $IMG $IMG.roothash $IMG_HASH $DEV_OUT $FEC_DEV $IMG_TMP >/dev/null 2>&1 LOOPDEV1="" LOOPDEV2="" } @@ -87,8 +89,7 @@ function compare_out() # $1 what, $2 expected 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=$($VERITYSETUP format $IMG $IMG_HASH --fec-device $FEC_DEV --fec-roots 2 -h sha256 | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ") ROOT_HASH_BAD=abcdef0000000000000000000000000000000000000000000000000000000000 $VERITYSETUP verify $IMG $IMG_HASH $ROOT_HASH || fail @@ -97,11 +98,13 @@ function check_root_hash_fail() $VERITYSETUP open $IMG $DEV_NAME $IMG_HASH $ROOT_HASH || fail check_exists + dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1 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 + dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=4096 count=1 >/dev/null 2>&1 dmsetup status $DEV_NAME | grep "verity C" >/dev/null || fail $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail @@ -110,6 +113,10 @@ function check_root_hash_fail() function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 offset] { + local FORMAT_PARAMS + local VERIFY_PARAMS + local ROOT_HASH + if [ -z "$LOOPDEV2" ] ; then BLOCKS=$(($6 / $1)) DEV_PARAMS="$LOOPDEV1 $LOOPDEV1 \ @@ -119,6 +126,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 DEV_PARAMS="$LOOPDEV1 $LOOPDEV2" fi + for root_hash_as_file in yes no; do for sb in yes no; do FORMAT_PARAMS="--format=$4 --data-block-size=$1 --hash-block-size=$1 --hash=$5 --salt=$3" if [ $sb == yes ] ; then @@ -127,20 +135,34 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 FORMAT_PARAMS="$FORMAT_PARAMS --no-superblock" VERIFY_PARAMS=$FORMAT_PARAMS fi + if [ $root_hash_as_file == yes ] ; then + echo -n $2 > $IMG.roothash + FORMAT_PARAMS="$FORMAT_PARAMS --root-hash-file=$IMG.roothash" + VERIFY_PARAMS="$VERIFY_PARAMS --root-hash-file=$IMG.roothash" + ROOT_HASH="" + else + ROOT_HASH="$2" + fi for fail in data hash; do wipe - echo -n "V$4(sb=$sb) $5 block size $1: " - $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT || fail + echo -n "V$4(sb=$sb root_hash_as_file=$root_hash_as_file) $5 block size $1: " + $VERITYSETUP format $DEV_PARAMS $FORMAT_PARAMS >$DEV_OUT + if [ $? -ne 0 ] ; then + if [[ $1 =~ "sha2" ]] ; then + fail "Cannot format device." + fi + return + fi echo -n "[root hash]" compare_out "root hash" $2 compare_out "salt" "$3" - $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || fail + $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || fail echo -n "[verify]" - $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || fail + $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || fail check_exists echo -n "[activate]" @@ -165,9 +187,9 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 ;; esac - $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 && \ + $VERITYSETUP verify $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 && \ fail "userspace check for $TXT corruption" - $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $2 >>$DEV_OUT 2>&1 || \ + $VERITYSETUP create $DEV_NAME $DEV_PARAMS $VERIFY_PARAMS $ROOT_HASH >>$DEV_OUT 2>&1 || \ fail "activation" dd if=/dev/mapper/$DEV_NAME of=/dev/null bs=$1 2>/dev/null dmsetup status $DEV_NAME | grep "verity V" >/dev/null && \ @@ -176,6 +198,7 @@ function check_root_hash() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, [$6 echo "[$TXT corruption]" done done + done } function corrupt_device() # $1 device, $2 device_size(in bytes), $3 #{corrupted_bytes} @@ -217,24 +240,20 @@ function check_fec() if [ "${11}" == "n" ]; then INDEX=24 echo -n "[no-superblock]" - PARAMS="$PARAMS --no-superblock -s=${12}" + PARAMS="$PARAMS --no-superblock --salt=${12}" elif [ -n "${12}" ]; then - PARAMS="$PARAMS -s=${12}" + PARAMS="$PARAMS --salt=${12}" fi if [[ "$1" == "$2" && "$1" == "$3" ]]; then echo -n "[one_device_test]" dd if=/dev/zero of=$IMG_TMP bs=$4 count=$5 > /dev/null 2>&1 - ARR=(`sha256sum $IMG_TMP`) - HASH_ORIG=${ARR[0]} + HASH_ORIG=$(sha256sum $IMG_TMP | cut -d' ' -f 1) else - ARR=(`sha256sum $1`) - HASH_ORIG=${ARR[0]} + HASH_ORIG=$(sha256sum $1 | cut -d' ' -f 1) fi - ARR=(`$VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS`) - SALT=${ARR[$INDEX]} - ROOT_HASH=${ARR[$(($INDEX+3))]} + ROOT_HASH=$($VERITYSETUP format $1 $2 --fec-device=$3 $PARAMS | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ") corrupt_device $1 $(($5 * $4)) ${10} @@ -244,12 +263,10 @@ function check_fec() return 3 fi - udevadm settle + udevadm settle > /dev/null 2>&1 dd if=/dev/mapper/$DEV_NAME of=$IMG_TMP > /dev/null 2>&1 - ARR=(`sha256sum $IMG_TMP`) - - HASH_REPAIRED=${ARR[0]} + HASH_REPAIRED=$(sha256sum $IMG_TMP | cut -d' ' -f 1) $VERITYSETUP close $DEV_NAME @@ -261,11 +278,11 @@ function check_fec() 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 + echo "[userspace verify][OK]" + RET=0 + fi rm $1 $2 $3 $IMG_TMP > /dev/null 2>&1 - return $RET + return $RET } function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI option, $7 status option @@ -285,7 +302,7 @@ function check_option() # $1 size, $2 hash, $3 salt, $4 version, $5 hash, $6 CLI function valgrind_setup() { - which valgrind >/dev/null 2>&1 || fail "Cannot find valgrind." + command -v valgrind >/dev/null || fail "Cannot find valgrind." [ ! -f $VERITYSETUP_VALGRIND ] && fail "Unable to get location of veritysetup executable." export LD_LIBRARY_PATH="$VERITYSETUP_LIB_VALGRIND:$LD_LIBRARY_PATH" } @@ -362,8 +379,7 @@ function checkUserSpaceRepair() echo -n "[nroots::$3]" - ARR=(`$VERITYSETUP format $IMG $HASH_DEV --fec-device $FEC $PARAMS --salt=$DEV_SALT --uuid=$DEV_UUID`) - ROOT_HASH=${ARR[28]} + ROOT_HASH=$($VERITYSETUP format $IMG $HASH_DEV --fec-device $FEC $PARAMS --salt=$DEV_SALT --uuid=$DEV_UUID | grep -e "Root hash" | cut -d: -f2 | tr -d "\t\n ") echo -n "[Errors can be corrected]" corrupt_device $IMG $(($BS*$COUNT)) $7 @@ -380,6 +396,33 @@ function checkUserSpaceRepair() echo "[OK]" } +function check_concurrent() # $1 hash +{ + DEV_PARAMS="$LOOPDEV1 $LOOPDEV2" + + # First check that with two sequential opens, we are returning the expected -EEXIST + $VERITYSETUP format $DEV_PARAMS >/dev/null 2>&1 || fail + $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 >/dev/null 2>&1 || fail + check_exists + $VERITYSETUP create $DEV_NAME $DEV_PARAMS $1 2>&1 >/dev/null | grep -q "Device $DEV_NAME already exists" || fail + $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail + + # Then do two concurrent opens, and check that libdevmapper did not return -EINVAL, which is + # not gracefully recoverable. Either could fail depending on scheduling, so just check that + # the libdevmapper error does not appear in either of the outputs. + cat /dev/null >$DEV_OUT + $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 & + $VERITYSETUP create -v $DEV_NAME $DEV_PARAMS $1 >>$DEV_OUT 2>&1 & + wait + grep -q "Command failed with code .* (wrong or missing parameters)" $DEV_OUT && fail + check_exists + rm $DEV_OUT + $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 || fail + + echo "[OK]" +} + +export LANG=C [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." [ ! -x "$VERITYSETUP" ] && skip "Cannot find $VERITYSETUP, test skipped." @@ -434,6 +477,11 @@ if check_version 1 3; then if check_version 1 7; then check_option 512 $HASH $SALT 1 sha256 "--panic-on-corruption" "panic_on_corruption" fi + + if check_version 1 9; then + echo "Verity data performance options test." + check_option 512 $HASH $SALT 1 sha256 "--use-tasklets" "try_verify_in_tasklet" + fi fi echo "Veritysetup [hash-offset bigger than 2G works] " @@ -480,5 +528,32 @@ checkUserSpaceRepair -1 4096 2 0 0 3 10 checkUserSpaceRepair 400 4096 2 2048000 0 2 1 checkUserSpaceRepair 500 4096 2 2457600 4915200 1 2 +echo -n "Verity concurrent opening tests:" +prepare 8192 1024 +check_concurrent 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 + +echo -n "Deferred removal of device:" +prepare 8192 1024 +$VERITYSETUP format $LOOPDEV1 $IMG_HASH --format=1 --data-block-size=512 --hash-block-size=512 --hash=sha256 --salt=$SALT >/dev/null 2>&1 || fail "Cannot format device." +$VERITYSETUP open $LOOPDEV1 $DEV_NAME $DEV $IMG_HASH 9de18652fe74edfb9b805aaed72ae2aa48f94333f1ba5c452ac33b1c39325174 || fail "Cannot activate device." +dmsetup create $DEV_NAME2 --table "0 8 linear /dev/mapper/$DEV_NAME 0" +[ ! -b /dev/mapper/$DEV_NAME2 ] && fail +$VERITYSETUP close $DEV_NAME >/dev/null 2>&1 && fail +$VERITYSETUP status $DEV_NAME >/dev/null 2>&1 || fail +$VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1 +if [ $? -eq 0 ] ; then + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" || fail + $VERITYSETUP close --cancel-deferred $DEV_NAME >/dev/null 2>&1 + dmsetup info $DEV_NAME | grep -q "DEFERRED REMOVE" >/dev/null 2>&1 && fail + $VERITYSETUP close --deferred $DEV_NAME >/dev/null 2>&1 + dmsetup remove $DEV_NAME2 || fail + $VERITYSETUP status $DEV_NAME >/dev/null 2>&1 && fail + echo "[OK]" +else + dmsetup remove $DEV_NAME2 >/dev/null 2>&1 + $VERITYSETUP close $DEV_NAME >/dev/null 2>&1 + echo "[N/A]" +fi + remove_mapping exit 0 diff --git a/tests/xfs_512_block_size.img.xz b/tests/xfs_512_block_size.img.xz Binary files differnew file mode 100644 index 0000000..047c788 --- /dev/null +++ b/tests/xfs_512_block_size.img.xz |