185 lines
6.5 KiB
Text
185 lines
6.5 KiB
Text
#! @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 <http://www.gnu.org/licenses/>.
|
|
|
|
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"'
|
|
|
|
_testcase() {
|
|
local EXPECTEDRES=$1
|
|
local LOGPREFIX=$2
|
|
local res=0
|
|
local output
|
|
shift 2
|
|
|
|
# Create a subdir in TMPDIR for each testcase
|
|
_TMPDIR=$TMPDIR
|
|
TMPDIR=$TMPDIR/`echo -n "$(date +%s).$LOGPREFIX" | sed -e 's,[ /],_,g' -e 's,:$,,g'`
|
|
mkdir -p "$TMPDIR"
|
|
|
|
output=`"$@" 2>&1` || res=$?
|
|
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'"
|
|
|
|
# TODO: Expect a failure with LUKS2 volumes with argon2 key derivation
|
|
eval testcase_fail "'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"
|
|
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'"
|
|
|
|
exit 0
|