tests/vb2_firmware_tests: Improve workbuffer usage test

This patch changes vb2_firmware_tests to run multiple times with
different combinations of signature and hash algorithms. The goal is to
have more confidence that our recommended work buffer size is still big
enough even if we changed algorithm combinations in an RW update. It
also changes the underlying vb20_verify_fw to not just print the amount
of work buffer used at the end, but to detect the actual high water mark
of work buffer used during the test.

Also add some fallback definitions for undefined environment variables
to tests/common.sh which helps running individual test scripts without
the Makefile harness.

BRANCH=None
BUG=None
TEST=make runtests

Change-Id: I14519cd7c76a9886bd11ebf5312458ab658e6f75
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1967976
Reviewed-by: Joel Kitching <kitching@chromium.org>
diff --git a/tests/common.sh b/tests/common.sh
index 8cc1498..70743fc 100644
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -6,8 +6,11 @@
 
 # Determine script directory.
 SCRIPT_DIR=$(dirname $(readlink -f "$0"))
-
 ROOT_DIR="$(dirname ${SCRIPT_DIR})"
+SRCDIR="${SRCDIR:-${ROOT_DIR}}"
+BUILD="${BUILD:-${ROOT_DIR}/build}"
+BUILD_RUN="${BUILD_RUN:-${BUILD}}"
+SRC_RUN="${SRC_RUN:-${SRCDIR}}"
 BUILD_DIR="${BUILD}"
 BIN_DIR=${BUILD_DIR}/install_for_test/bin
 FUTILITY=${BIN_DIR}/futility
diff --git a/tests/vb20_verify_fw.c b/tests/vb20_verify_fw.c
index 4e107cf..e2a5471 100644
--- a/tests/vb20_verify_fw.c
+++ b/tests/vb20_verify_fw.c
@@ -146,7 +146,8 @@
 
 int main(int argc, char *argv[])
 {
-	uint8_t workbuf[16384] __attribute__((aligned(VB2_WORKBUF_ALIGN)));
+	uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
+		__attribute__((aligned(VB2_WORKBUF_ALIGN)));
 	struct vb2_context *ctx;
 	struct vb2_shared_data *sd;
 	vb2_error_t rv;
@@ -161,6 +162,11 @@
 	vblock_fname = argv[2];
 	body_fname = argv[3];
 
+	/* Intialize workbuf with sentinel value to see how much we'll use. */
+	uint32_t *ptr = (uint32_t *)workbuf;
+	while ((uint8_t *)ptr + sizeof(*ptr) <= workbuf + sizeof(workbuf))
+		*ptr++ = 0xbeefdead;
+
 	/* Set up context */
 	if (vb2api_init(workbuf, sizeof(workbuf), &ctx)) {
 		printf("Failed to initialize workbuf.\n");
@@ -211,7 +217,10 @@
 
 	printf("Yaay!\n");
 
-	printf("Workbuf used = %d bytes\n", sd->workbuf_used);
+	while ((uint8_t *)ptr > workbuf && *--ptr == 0xbeefdead)
+		/* find last used workbuf offset */;
+	printf("Workbuf used = %d bytes, high watermark = %zu bytes\n",
+		sd->workbuf_used, (uint8_t *)ptr + sizeof(*ptr) - workbuf);
 
 	return 0;
 }
diff --git a/tests/vb2_firmware_tests.sh b/tests/vb2_firmware_tests.sh
index 00f3afd..88b6e6a 100755
--- a/tests/vb2_firmware_tests.sh
+++ b/tests/vb2_firmware_tests.sh
@@ -23,36 +23,77 @@
 echo 'This is a test firmware body.  This is only a test.  Lalalalala' \
     > body.test
 
-# Pack keys using original vboot utilities
-${FUTILITY} vbutil_key --pack rootkey.test \
-    --key ${TESTKEY_DIR}/key_rsa8192.keyb --algorithm 11
-${FUTILITY} vbutil_key --pack fwsubkey.test \
-    --key ${TESTKEY_DIR}/key_rsa4096.keyb --algorithm 7
-${FUTILITY} vbutil_key --pack kernkey.test \
-    --key ${TESTKEY_DIR}/key_rsa2048.keyb --algorithm 4
+algo_to_rsa()
+{
+	case $1 in
+	0|1|2) printf "rsa1024";;
+	3|4|5) printf "rsa2048";;
+	6|7|8) printf "rsa4096";;
+	9|10|11) printf "rsa8192";;
+	*) exit 1;;
+	esac
+}
 
-# Create a GBB with the root key
-${FUTILITY} gbb -c 128,2400,0,0 gbb.test
-${FUTILITY} gbb gbb.test -s --hwid='Test GBB' \
-  --rootkey=rootkey.test
+algo_to_sha()
+{
+	case $1 in
+	0|3|6|9) printf "sha1";;
+	1|4|7|10) printf "sha256";;
+	2|5|8|11) printf "sha512";;
+	*) exit 1;;
+	esac
+}
 
-# Keyblock with firmware subkey is signed by root key
-${FUTILITY} vbutil_keyblock --pack keyblock.test \
-    --datapubkey fwsubkey.test \
-    --signprivate ${TESTKEY_DIR}/key_rsa8192.sha512.vbprivk
+run_test()
+{
+	local root_algo=$1
+	local fw_algo=$2
+	local kern_algo=$3
 
-# Firmware preamble is signed with the firmware subkey
-${FUTILITY} vbutil_firmware \
-    --vblock vblock.test \
-    --keyblock keyblock.test \
-    --signprivate ${TESTKEY_DIR}/key_rsa4096.sha256.vbprivk \
-    --fv body.test \
-    --version 1 \
-    --kernelkey kernkey.test
+	local root_rsa="$(algo_to_rsa ${root_algo})"
+	local fw_rsa="$(algo_to_rsa ${fw_algo})"
+	local kern_rsa="$(algo_to_rsa ${kern_algo})"
 
-echo 'Verifying test firmware using vb2_verify_fw'
+	local root_sha="$(algo_to_sha ${root_algo})"
+	local fw_sha="$(algo_to_sha ${fw_algo})"
+	local kern_sha="$(algo_to_sha ${kern_algo})"
 
-# Verify the firmware using vboot2 checks
-${BUILD_RUN}/tests/vb20_verify_fw gbb.test vblock.test body.test
+	# Pack keys using original vboot utilities
+	${FUTILITY} vbutil_key --pack rootkey.test \
+	    --key "${TESTKEY_DIR}/key_${root_rsa}.keyb" --algorithm ${root_algo}
+	${FUTILITY} vbutil_key --pack fwsubkey.test \
+	    --key "${TESTKEY_DIR}/key_${fw_rsa}.keyb" --algorithm ${fw_algo}
+	${FUTILITY} vbutil_key --pack kernkey.test \
+	    --key "${TESTKEY_DIR}/key_${kern_rsa}.keyb" --algorithm ${kern_algo}
 
-happy 'vb2_verify_fw succeeded'
+	# Create a GBB with the root key
+	${FUTILITY} gbb -c 128,2400,0,0 gbb.test
+	${FUTILITY} gbb gbb.test -s --hwid='Test GBB' \
+	  --rootkey=rootkey.test
+
+	# Keyblock with firmware subkey is signed by root key
+	${FUTILITY} vbutil_keyblock --pack keyblock.test \
+	    --datapubkey fwsubkey.test \
+	    --signprivate "${TESTKEY_DIR}/key_${root_rsa}.${root_sha}.vbprivk"
+
+	# Firmware preamble is signed with the firmware subkey
+	${FUTILITY} vbutil_firmware \
+	    --vblock vblock.test \
+	    --keyblock keyblock.test \
+	    --signprivate "${TESTKEY_DIR}/key_${fw_rsa}.${fw_sha}.vbprivk" \
+	    --fv body.test \
+	    --version 1 \
+	    --kernelkey kernkey.test
+
+	echo "Verifying test firmware using vb2_verify_fw" \
+		"(root=${root_algo}, fw=${fw_algo}, kernel=${kern_algo})"
+
+	# Verify the firmware using vboot2 checks
+	${BUILD_RUN}/tests/vb20_verify_fw gbb.test vblock.test body.test
+
+	happy 'vb2_verify_fw succeeded'
+}
+
+run_test 11 7 4
+run_test 11 11 11
+run_test 1 1 1