1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2009 IBM Corporation
4# Copyright (c) 2018 Petr Vorel <pvorel@suse.cz>
5# Author: Mimi Zohar <zohar@linux.ibm.com>
6#
7# Verify the boot and PCR aggregates.
8
9TST_CNT=2
10TST_NEEDS_CMDS="awk cut ima_boot_aggregate"
11
12. ima_setup.sh
13
14test1()
15{
16	tst_res TINFO "verify boot aggregate"
17
18	local zero="0000000000000000000000000000000000000000"
19	local tpm_bios="$SECURITYFS/tpm0/binary_bios_measurements"
20	local ima_measurements="$ASCII_MEASUREMENTS"
21	local boot_aggregate boot_hash line
22
23	# IMA boot aggregate
24	read line < $ima_measurements
25	boot_hash=$(echo $line | awk '{print $(NF-1)}' | cut -d':' -f2)
26
27	if [ ! -f "$tpm_bios" ]; then
28		tst_res TINFO "TPM Hardware Support not enabled in kernel or no TPM chip found"
29
30		if [ "${boot_hash}" = "${zero}" ]; then
31			tst_res TPASS "bios boot aggregate is 0"
32		else
33			tst_res TFAIL "bios boot aggregate is not 0"
34		fi
35	else
36		boot_aggregate=$(ima_boot_aggregate $tpm_bios | grep "boot_aggregate:" | cut -d':' -f2)
37		if [ "${boot_hash}" = "${boot_aggregate}" ]; then
38			tst_res TPASS "bios aggregate matches IMA boot aggregate"
39		else
40			tst_res TFAIL "bios aggregate does not match IMA boot aggregate"
41		fi
42	fi
43}
44
45# Probably cleaner to programmatically read the PCR values directly
46# from the TPM, but that would require a TPM library. For now, use
47# the PCR values from /sys/devices.
48validate_pcr()
49{
50	tst_res TINFO "verify PCR (Process Control Register)"
51
52	local dev_pcrs="$1"
53	local pcr hash aggregate_pcr
54
55	aggregate_pcr="$(evmctl -v ima_measurement $BINARY_MEASUREMENTS 2>&1 | \
56		grep 'HW PCR-10:' | awk '{print $3}')"
57	if [ -z "$aggregate_pcr" ]; then
58		tst_res TFAIL "failed to get PCR-10"
59		return 1
60	fi
61
62	while read line; do
63		pcr="$(echo $line | cut -d':' -f1)"
64		if [ "${pcr}" = "PCR-10" ]; then
65			hash="$(echo $line | cut -d':' -f2 | awk '{ gsub (" ", "", $0); print tolower($0) }')"
66			[ "${hash}" = "${aggregate_pcr}" ]
67			return $?
68		fi
69	done < $dev_pcrs
70	return 1
71}
72
73test2()
74{
75	tst_res TINFO "verify PCR values"
76	tst_check_cmds evmctl
77
78	tst_res TINFO "evmctl version: $(evmctl --version)"
79
80	local pcrs_path="/sys/class/tpm/tpm0/device/pcrs"
81	if [ -f "$pcrs_path" ]; then
82		tst_res TINFO "new PCRS path, evmctl >= 1.1 required"
83	else
84		pcrs_path="/sys/class/misc/tpm0/device/pcrs"
85	fi
86
87	if [ -f "$pcrs_path" ]; then
88		validate_pcr $pcrs_path
89		if [ $? -eq 0 ]; then
90			tst_res TPASS "aggregate PCR value matches real PCR value"
91		else
92			tst_res TFAIL "aggregate PCR value does not match real PCR value"
93		fi
94	else
95		tst_res TCONF "TPM Hardware Support not enabled in kernel or no TPM chip found"
96	fi
97}
98
99tst_run
100