#!/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

[ -z "$srcdir" ] && srcdir="."

function remove_mapping()
{
	[ -b /dev/mapper/$MAP ] && dmsetup remove --retry $MAP
}

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."
	exit 77
}

function test_one()
{
	$CRYPTSETUP benchmark -c "$1" -s "$2" | grep -v "#" || skip
}

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

	echo "REQUIRED CIPHERS TEST"
	echo "#     Algorithm | Key |  Encryption |  Decryption"

	test_one aes-xts 256
	test_one twofish-xts 256
	test_one serpent-xts 256
	test_one aes-cbc 256
	test_one aes-lrw 256
}

export LANG=C

test_required
[ ! -d $TST_DIR ] && tar xJf $srcdir/luks1-images.tar.xz --no-same-owner

echo "PASSPHRASE CHECK"
for file in $(ls $TST_DIR/luks1_*) ; do
	echo -n " $file"
	$CRYPTSETUP luksOpen -d $TST_DIR/$KEYFILE $file --test-passphrase 2>/dev/null
	ret=$?
	# ignore missing whirlpool (pwd failed is exit code 2)
	[ $ret -eq 1 ] && (echo $file | grep -q -e "whirlpool") && echo " [N/A]" && continue
	# ignore flawed whirlpool (pwd failed is exit code 2)
	[ $ret -eq 2 ] && (echo $file | grep -q -e "whirlpool") && \
		($CRYPTSETUP luksDump $file --debug | grep -q -e "flawed whirlpool") && \
		echo " [IGNORED (flawed Whirlpool library)]" && continue
	[ $ret -ne 0 ] && fail
	echo " [OK]"
done

if [ $(id -u) != 0 ]; then
	echo "WARNING: You must be root to run activation part of test, test skipped."
	exit 0
fi

echo "ACTIVATION FS UUID CHECK"
for file in $(ls $TST_DIR/luks1_*) ; do
	echo -n " $file"
	$CRYPTSETUP luksOpen -d $TST_DIR/$KEYFILE $file $MAP 2>/dev/null
	ret=$?
	# ignore missing whirlpool (pwd failed is exit code 2)
	[ $ret -eq 1 ] && (echo $file | grep -q -e "whirlpool") && echo " [N/A]" && continue
	# ignore flawed whirlpool (pwd failed is exit code 2)
	[ $ret -eq 2 ] && (echo $file | grep -q -e "whirlpool") && \
		($CRYPTSETUP luksDump $file --debug | grep -q -e "flawed whirlpool") && \
		echo " [IGNORED (flawed Whirlpool library)]" && 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)
	$CRYPTSETUP remove $MAP || fail
	[ "$UUID" != "DEAD-BABE" ] && fail "UUID check failed."
	echo " [OK]"
done
