Add a new test script, tests/mfa_key_protector_test.in, to verify the functionality of the Multi-Factor Authentication (MFA) key protector.
This test performs the following steps: 1. Creates a LUKS2 encrypted partition using a combined key derived from a random key file (Factor 1) and a passphrase (Factor 2). 2. Configures GRUB with the mfa module, initializing the file key protector for Factor 1 and the password key protector for Factor 2. 3. Verifies that "cryptomount -a --protector mfa" successfully combines the factors to unlock the volume. Signed-off-by: Gary Lin <[email protected]> --- Makefile.util.def | 6 ++ tests/mfa_key_protector_test.in | 123 ++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 tests/mfa_key_protector_test.in diff --git a/Makefile.util.def b/Makefile.util.def index 313dd0a68..f1ae5dd54 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -1305,6 +1305,12 @@ script = { common = tests/tpm2_key_protector_test.in; }; +script = { + testcase = native; + name = mfa_key_protector_test; + common = tests/mfa_key_protector_test.in; +}; + program = { testcase = native; name = example_unit_test; diff --git a/tests/mfa_key_protector_test.in b/tests/mfa_key_protector_test.in new file mode 100644 index 000000000..73cf695c1 --- /dev/null +++ b/tests/mfa_key_protector_test.in @@ -0,0 +1,123 @@ +#! @BUILD_SHEBANG@ -e + +# Test GRUBs ability to unlock a LUKS partition using the MFA key protector +# (File + Password combination) +# +# Copyright (C) 2025 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. + +grubshell=@builddir@/grub-shell + +. "@builddir@/grub-core/modinfo.sh" + +if [ x${grub_modinfo_platform} != xemu ]; then + exit 77 +fi + +builddir="@builddir@" + +# Force build directory components +PATH="${builddir}:${PATH}" +export PATH + +if [ "x${EUID}" = "x" ] ; then + EUID=`id -u` +fi + +if [ "${EUID}" != 0 ] ; then + echo "not root; cannot test mfa." + exit 99 +fi + +if ! command -v cryptsetup >/dev/null 2>&1; then + echo "cryptsetup not installed; cannot test mfa." + exit 99 +fi + +mfatestdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`" || exit 99 + +disksize=20M + +passphrase="top secret" +luksfile=${mfatestdir}/luks.disk +keypart1=${mfatestdir}/key_part1.bin +keypart2=${mfatestdir}/key_part2.txt +lukskeyfile=${mfatestdir}/luks_key.bin + +# Choose a low iteration number to reduce the time to decrypt the disk +csopt="--type luks2 --pbkdf pbkdf2 --iter-time 1000" + +timeout=20 +testoutput=${mfatestdir}/testoutput +vtext="TEST VERIFIED" + +# Cleanup on exit +cleanup() { + RET=$? + if [ "${RET}" -eq 0 ]; then + rm -rf "$mfatestdir" || : + fi +} +trap cleanup EXIT INT TERM KILL QUIT + +ret=0 + +# Part 1: A random binary file (Factor 1) +dd if=/dev/urandom of="${keypart1}" bs=1 count=64 >/dev/null 2>&1 + +# Part 2: A password (Factor 2) +echo -n "${passphrase}" > "${keypart2}" + +# Combine them to create the actual LUKS Key +cat "${keypart1}" "${keypart2}" > "${lukskeyfile}" + +# Setup the LUKS2 image with the combined key +truncate -s ${disksize} "${luksfile}" || exit 99 +cryptsetup luksFormat -q ${csopt} "${luksfile}" "${lukskeyfile}" || exit 99 + +# Open the device to write the verification text +luksdev=/dev/mapper/`basename "${mfatestdir}"` +cryptsetup open --key-file "${lukskeyfile}" "${luksfile}" `basename "${luksdev}"` || exit 99 + +# Write "TEST VERIFIED" to the start of the mapped device +echo "${vtext}" > "${luksdev}" + +# Close the device +cryptsetup close "${luksdev}" + + +grub_cfg=${mfatestdir}/testcase.cfg + +# Generate the GRUB script. +# We use the explicit 'pw_key_protector_init' with '-p' to automate the password entry +# so the test does not hang waiting for user input. +cat > "${grub_cfg}" <<EOF +loopback luks (host)${luksfile} +file_key_protector_init -k (host)${keypart1} +pw_key_protector_init -p "${passphrase}" +mfa_key_protector_init -1 file -2 password +if cryptomount -a --protector mfa; then + cat (crypto0)+1 +fi +EOF + +${grubshell} --timeout=${timeout} < "${grub_cfg}" > "${testoutput}" || ret=$? + +if [ "${ret}" -eq 0 ]; then + if grep -q "^${vtext}$" "${testoutput}"; then + echo "MFA [File + Password]: PASS" + exit 0 + else + echo "MFA [File + Password]: FAIL (Verification text not found)" + echo "Output was:" + cat "${testoutput}" + exit 1 + fi +else + echo "grub-emu exited with error: ${ret}" >&2 + exit 99 +fi -- 2.51.0 _______________________________________________ Grub-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/grub-devel
