#! @BUILD_SHEBANG@ -e # Run all grub cryptomount tests in a Qemu instance # Copyright (C) 2023 Free Software Foundation, Inc. # # GRUB 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 3 of the License, or # (at your option) any later version. # # GRUB 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 GRUB. If not, see . if [ "x$EUID" = "x" ] ; then EUID=`id -u` fi if [ "$EUID" != 0 ] ; then echo "not root; cannot test cryptomount." exit 99 fi if ! which cryptsetup >/dev/null 2>&1; then echo "cryptsetup not installed; cannot test cryptomount." exit 99 fi if ! which mkfs.vfat >/dev/null 2>&1; then echo "mkfs.vfat not installed; cannot test cryptomount." exit 99 fi COMMON_OPTS='${V:+--debug=$V} --cs-opts="--pbkdf-force-iterations 1000"' debug=${GRUB_SHELL_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG} builddir="@builddir@" _testcase() { local EXPECTEDRES=$1 local LOGPREFIX=$2 local res=0 local output shift 2 # Create a subdir in TMPDIR for each testcase _TMPDIR=${TMPDIR:-/tmp} TMPDIR=${_TMPDIR}/`echo -n "$(date +%s).${LOGPREFIX}" | sed -e 's,[ /],_,g' -e 's,:$,,g'` export TMPDIR mkdir -p "$TMPDIR" set -- "$@" $([ "${EXPECTEDRES}" -eq 1 ] && echo "--xfail") output=`"$@" 2>&1` || res=$? if [ -z "$debug" ]; then if ! rmdir "$TMPDIR" >/dev/null 2>&1; then echo echo "Note: Temporary directory cannot be removed:" echo " $TMPDIR" echo " Please inspect and remove manually." echo fi fi TMPDIR=$_TMPDIR if [ "$res" -eq "$EXPECTEDRES" ]; then if [ "$res" -eq 0 ]; then echo $LOGPREFIX PASS else echo $LOGPREFIX XFAIL fi else echo "Error[$res]: $output" if [ "$res" -eq 0 ]; then echo $LOGPREFIX XPASS elif [ "$res" -eq 1 ]; then echo $LOGPREFIX FAIL else # Any exit code other than 1 or 0, indicates a hard error, # not a test error echo $LOGPREFIX ERROR return 99 fi return 1 fi } testcase() { _testcase 0 "$@"; } testcase_fail() { _testcase 1 "$@"; } ### LUKS1 tests eval testcase "'LUKS1 test cryptsetup defaults:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS eval testcase "'LUKS1 test with twofish cipher:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ "--cs-opts='--cipher twofish-xts-plain64'" eval testcase "'LUKS1 test key file support:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ --keyfile eval testcase "'LUKS1 test key file with offset:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ --keyfile --cs-opts="--keyfile-offset=237" eval testcase "'LUKS1 test key file with offset and size:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'" eval testcase "'LUKS1 test detached header support:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ --detached-header eval testcase "'LUKS1 test both detached header and key file:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ --keyfile --detached-header ### LUKS2 tests (mirroring the LUKS1 tests above) LUKS2_COMMON_OPTS="--luks=2 --cs-opts=--pbkdf=pbkdf2" eval testcase "'LUKS2 test cryptsetup defaults:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS eval testcase "'LUKS2 test with twofish cipher:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--cipher twofish-xts-plain64'" eval testcase "'LUKS2 test key file support:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ --keyfile eval testcase "'LUKS2 test key file with offset:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ --keyfile --cs-opts="--keyfile-offset=237" eval testcase "'LUKS2 test key file with offset and size:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'" eval testcase "'LUKS2 test detached header support:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ --detached-header eval testcase "'LUKS2 test both detached header and key file:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ --keyfile --detached-header ### LUKS1 specific tests # Tests for xts-plain and xts-plain64 modes eval testcase "'LUKS1 test cryptsetup xts-plain:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ "--cs-opts='--cipher aes-xts-plain'" eval testcase "'LUKS1 test cryptsetup xts-plain64:'" \ "$builddir/grub-shell-luks-tester" --luks=1 $COMMON_OPTS \ "--cs-opts='--cipher aes-xts-plain64'" ### LUKS2 specific tests eval testcase "'LUKS2 test with 1k sector size:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--sector-size 1024'" eval testcase "'LUKS2 test with 2k sector size:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--sector-size 2048'" eval testcase "'LUKS2 test with 4k sector size:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--sector-size 4096'" eval testcase "'LUKS2 test with non-default key slot:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--key-slot 5'" eval testcase "'LUKS2 test with different metadata size:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-opts='--luks2-metadata-size 512k'" eval testcase "'LUKS2 test with argon2 pbkdf:'" \ "$builddir/grub-shell-luks-tester" --luks=2 $COMMON_OPTS \ "--cs-opts='--pbkdf-memory 32'" "--cs-opts='--pbkdf-parallel 1'" # Add good password to second slot and change first slot to unchecked password csscript=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 99 cat >$csscript <<'EOF' CSOPTS="--pbkdf-force-iterations 1000 --pbkdf=pbkdf2 --force-password" cryptsetup $CSOPTS --key-file $lukskeyfile luksAddKey $luksdiskfile $lukskeyfile echo "newpass" | cryptsetup $CSOPTS --key-file $lukskeyfile --key-slot 0 luksChangeKey $luksdiskfile EOF eval testcase "'LUKS2 test with second key slot and first slot using different password:'" \ "$builddir/grub-shell-luks-tester" $LUKS2_COMMON_OPTS $COMMON_OPTS \ "--cs-script='$csscript'" test -n "$debug" || rm "$csscript" exit 0