From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1k7bva-0000d2-7r for mharc-grub-devel@gnu.org; Mon, 17 Aug 2020 05:59:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33052) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k7bvY-0000cu-JM for grub-devel@gnu.org; Mon, 17 Aug 2020 05:59:40 -0400 Received: from mail-qt1-x831.google.com ([2607:f8b0:4864:20::831]:35026) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1k7bvW-00053a-Eq for grub-devel@gnu.org; Mon, 17 Aug 2020 05:59:40 -0400 Received: by mail-qt1-x831.google.com with SMTP id f19so7428504qtp.2 for ; Mon, 17 Aug 2020 02:59:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficientek-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I/UShz7VxqAo25Ya8TQXwWPTKJP7WMxchvyuEI3esHw=; b=VhwFVeU3uF/VoqKDX39DRQrbblTO4Fbf9Hwmb29VckU+zJb/lvLlUgWECw93s4MzhF 3etfolfffte+h41UsuJf7khKqARDR43gqio8cFgyYas79n32ImamIw4VvlH99vUVqsA9 Y099TaJ7kfFw8HN3rcyOYocc0G/8t4ePTar6dsaLgd+e6vHQALm+qLTDoawVmDOqwQcp Fh/dMff0f8D2+hrmQSJjEwJpdZ3d5HcryyStNBN7GcwLVMusKYKLpe7BF55U8C6gO0DJ 1KTbhPWu64sbh+iXkQEHZa8QbpW8uua7NGXZSICS6X3x/54YAoao2YIfrNeoohK6/ahY t8lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=I/UShz7VxqAo25Ya8TQXwWPTKJP7WMxchvyuEI3esHw=; b=ALKX6c9MAYCXf9tOy/6X03wTkeCYwnYrGw/nWpNSSAKCt+stebeHEVJQz1npmtNSPN VM7f3u3S8k5eUH8L7kG6R6t7GfR6G+sNg5M1Lb97YFSJ8kw+/VFuYJwus+eRgO/+2kH/ 6V4AvUHxCSI06SFm7wabS6pdz6rBg7beO9W8LnncSCZhbWzMHtIKJL13RhbmVX9LEBZ6 IDy0TdYSgWMUEJH1/93/3i9h9EILBMdVxSQJOQ4fktWb95t6u1xHdxdcbqNjLYdjoEfE QJD0RY9U5mpQ+F0SMUrEcdf3fLaTGXdYbQ5W03ojvhsd/Qya+FL1gX5u/bWQwVvCIqHR 3gJw== X-Gm-Message-State: AOAM530fFZ9lmWzE5lISweCUnCGgWaOAUlAZK0FOd5exRUKHxVUwaCO+ i+HgCnH6oSgVwOiQ8wQkPjDT24wSBbuQZg== X-Google-Smtp-Source: ABdhPJzmOMNzbr6sPXl/9Z3IjGCSzyg49XtShVtwhmpNMqvUk+PUqbWNKrCaEIIOqasZYa76GtONcw== X-Received: by 2002:aed:3fa9:: with SMTP id s38mr13213208qth.237.1597658376797; Mon, 17 Aug 2020 02:59:36 -0700 (PDT) Received: from crass-HP-ZBook-15-G2.lan ([136.49.44.103]) by smtp.gmail.com with ESMTPSA id a203sm16517670qkg.30.2020.08.17.02.59.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 02:59:36 -0700 (PDT) From: Glenn Washburn To: grub-devel@gnu.org Cc: Glenn Washburn Subject: [CRYPTOMOUNT-TEST v2 6/7] tests: Add grub-shell-luks-tester to facilitate functional LUKS1/2 testing. Date: Mon, 17 Aug 2020 04:59:07 -0500 Message-Id: <20200817095907.15058-1-development@efficientek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200817000518.4006518-7-development@efficientek.com> References: <20200817000518.4006518-7-development@efficientek.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::831; envelope-from=development@efficientek.com; helo=mail-qt1-x831.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Aug 2020 09:59:40 -0000 Signed-off-by: Glenn Washburn --- Makefile.util.def | 6 + tests/util/grub-shell-luks-tester.in | 321 +++++++++++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 tests/util/grub-shell-luks-tester.in diff --git a/Makefile.util.def b/Makefile.util.def index d9e2bd84d..cfc71f1ab 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -742,6 +742,12 @@ script = { installdir = noinst; }; +script = { + name = grub-shell-luks-tester; + common = tests/util/grub-shell-luks-tester.in; + installdir = noinst; +}; + script = { name = grub-fs-tester; common = tests/util/grub-fs-tester.in; diff --git a/tests/util/grub-shell-luks-tester.in b/tests/util/grub-shell-luks-tester.in new file mode 100644 index 000000000..131045f77 --- /dev/null +++ b/tests/util/grub-shell-luks-tester.in @@ -0,0 +1,321 @@ +#! @BUILD_SHEBANG@ -e + +# Compares GRUB script output with BASH output. +# Copyright (C) 2009,2010 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 . + +# Initialize some variables. +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +builddir="@builddir@" +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ + +# Force build directory components +PATH="${builddir}:$PATH" +export PATH + +detached_header= +keyfile= +keyfile_offset= +keyfile_size= +KEYFILE_SIZE_MAX=4096 + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + -d | --debug) + debug=$((${debug:-0}+1)) ;; + --modules=*) + ms=`echo "$option" | sed -e 's/--modules=//'` + modules="$modules,$ms" ;; + --qemu-opts=*) + qs=`echo "$option" | sed -e 's/--qemu-opts=//'` + qemuopts="$qemuopts $qs" ;; + --cs-opts=*) + qs=`echo "$option" | sed -e 's/--cs-opts=//'` + csopts="$csopts $qs" ;; + --luks=*) + qs=`echo "$option" | sed -e 's/--luks=//'` + csopts="$csopts --type luks$qs" ;; + --detached-header) + detached_header=1 ;; + --keyfile=*) + qs=`echo "$option" | sed -e 's/--keyfile=//'` + keyfile="$qs" ;; + --keyfile) + keyfile=1 ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 3 + ;; + *) + if [ "x${source}" != x ] ; then + echo "too many parameters at the end" 1>&2 + usage + exit 4 + fi + source="${option}" ;; + esac +done + +[ "$debug" -gt 1 ] && set -x + +# Make sure that the dm-crypto device is shutdown +cleanup() { + if [ -e "$luksdev" ]; then + cryptsetup close "$luksdev" + fi + [ -z "$debug" ] && rm -rf "$lukstestdir" || : +} +trap cleanup EXIT INT TERM KILL QUIT + +get_random_bytes() { + local NUM_BYTES=$1 + dd if=/dev/urandom bs=512 count=$((($NUM_BYTES / 512)+2)) 2>/dev/null \ + | tr -d '\0' | dd bs=1 count=$(($NUM_BYTES)) 2>/dev/null +} + +# create a random directory to be hold generated files +lukstestdir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 20 +luksfile=$lukstestdir/luks.disk +lukshdrfile=$lukstestdir/luks.header +lukskeyfile=$lukstestdir/luks.key +vfile=$lukstestdir/mnt/test.verify +vtext="TEST VERIFIED" +testvars=$lukstestdir/testvars +testoutput=$lukstestdir/testoutput +password=testpass + +[ -n "$debug" ] && echo "LUKS TEST directory: $lukstestdir" >&2 + +# If testing keyfiles, create a big one. +if [ -e "$keyfile" ]; then + password=`cat "$keyfile"` +elif [ -n "$keyfile" ]; then + password=`get_random_bytes $KEYFILE_SIZE_MAX` +fi + +if [ -n "$detached_header" ]; then + csopts="$csopts --header $lukshdrfile" +fi + +# create the key file +echo -n "$password" > $lukskeyfile + +# Create a very small LUKS container for the test +truncate -s 20M $luksfile || exit 21 + +# Format the luks disk file +cryptsetup luksFormat -q $csopts $luksfile $lukskeyfile || exit 22 + +# Look for --keyfile-offset and --keyfile-size options in the cryptsetup +# options, and process them specially. +csopen_opts= +get_args=0 +varname= +for option in $csopts; do + if [ "$get_args" -gt 0 ]; then + csopen_opts=" $csopen_opts $option" + get_args=$(($get_args - 1)) + eval ${varname}=$option + continue + fi + + case "$option" in + --keyfile-offset) + varname=keyfile_offset + get_args=1 ;; + --keyfile-offset=*) + keyfile_offset=`echo "$option" | sed -e 's/--keyfile-offset=//'` ;; + --keyfile-size | -l) + varname=keyfile_size + get_args=1 ;; + --keyfile-size=*) + keyfile_size=`echo "$option" | sed -e 's/--keyfile-size=//'` ;; + *) + continue ;; + esac + + csopen_opts=" $csopen_opts $option" +done + +# Open LUKS device +luksdev=/dev/mapper/`basename $lukstestdir` +cryptsetup open ${detached_header:+--header $lukshdrfile} $csopen_opts \ + --key-file $lukskeyfile $luksfile `basename $luksdev` || exit 23 + +# Make filesystem on the luks disk +mkfs.vfat $luksdev >/dev/null 2>&1 || exit 24 + +# Add verification file to filesystem +mkdir $lukstestdir/mnt +mount $luksdev $lukstestdir/mnt || exit 25 +echo "$vtext" > $vfile + +# Unmount filesystem +umount $lukstestdir/mnt || exit 26 + +. "@builddir@/grub-core/modinfo.sh" + +if [ x"${grub_modinfo_platform}" = xemu ]; then + grub_testvars="(host)$testvars" + grub_key_file="(host)$lukskeyfile" + grub_lukshdr_file="(host)$lukshdrfile" +else + grub_testvars="/testvars" + grub_key_file="/keyfile" + grub_lukshdr_file="/luks.header" +fi + + +# Can not use --disk with a raw LUKS container because it appears qemu +# tries to convert the image to and is failing with: +# "Parameter 'key-secret' is required for cipher" +qemuopts="$qemuopts -drive file=$luksfile,index=0,media=disk,format=raw" + +# Add crypto modules +modules="$modules cryptodisk luks luks2 fat" + +# Create randomly generated trim line +trim_line=`mktemp -u XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` + +# Create vars to import into grub script +cat >$testvars <>$testvars +fi + +grub_shell_opts="$grub_shell_opts --trim=${trim_line}" +if [ -n "$keyfile" ]; then + grub_shell_opts="$grub_shell_opts --files=${keyfile:+${grub_key_file}=${lukskeyfile}}" +fi + +if [ -n "$detached_header" ]; then + grub_shell_opts="$grub_shell_opts --files=${detached_header:+${grub_lukshdr_file}=${lukshdrfile}}" +fi + +# Run the test in grub-shell +@builddir@/grub-shell ${debug:+--debug} $grub_shell_opts \ + --modules="$modules" --qemu-opts="$qemuopts" \ + --files="${grub_testvars}=${testvars}" \ + >$testoutput <<'EOF' + +search -n -f --set=testvarsdev /testvars +if [ "$?" -ne 0 ]; then + echo "Could not find testvars file." + # FIXME: Apparently halt doesn't work on some platforms? + halt + reboot + exit +fi + +. ($testvarsdev)/testvars + +# If key file exists, use it instead of password +if [ -e "$grub_key_file" ]; then + cryptomount_opts="$cryptomount_opts -k $grub_key_file" +else + cryptomount_opts="$cryptomount_opts -p $grub_password" +fi + +if [ -n "$grub_keyfile_offset" ]; then + cryptomount_opts="$cryptomount_opts -O $grub_keyfile_offset" +fi + +if [ -n "$grub_keyfile_size" ]; then + cryptomount_opts="$cryptomount_opts -S $grub_keyfile_size" +fi + +if [ -e "$grub_lukshdr_file" ]; then + cryptomount_opts="$cryptomount_opts -H $grub_lukshdr_file" +fi + +cdisk=crypto0 + +if test -n "$grub_debug" -a "$grub_debug" -gt 0; then + echo cmd: cryptomount $cryptomount_opts (hd0) +elif test -n "$grub_debug" -a "$grub_debug" -gt 1; then + set debug=all +fi +cryptomount $cryptomount_opts (hd0) +ret="$?" +if test -n "$grub_debug" -a "$grub_debug" -eq 2; then + set debug= +fi + +echo "$trim_line" +if test $ret -eq 0; then + cat ($cdisk)/$vfilename +else + echo "cryptomount failed: $ret" +fi +EOF +ret=$? + +if [ "$ret" -eq 0 ]; then + v="`cat $testoutput`" + if test "$v" != "$vtext"; then echo "error: test not verified [$v]" >&2; exit 1; fi +else + echo "grub-shell exited with error: $ret" >&2 + exit 27 +fi + +exit $ret -- 2.25.1