From: David Jacobson <djacobs7@xxxxxxxxxxxxxx> The first record in the IMA runtime measurement list is the boot aggregate - a hash of PCRs 0-7. This test calculates the boot aggregate based off the PCRs and compares it to IMA's boot aggregate. Dependencies: a TPM, IBMTSS2. Signed-off-by: David Jacobson <djacobs7@xxxxxxxxxxxxxx> Changelog: * Added boot_aggregate to test list * shellcheck compliant * minor fixes * move from functions to tests * redid tss parsing * checkbashisms complaint * remove begin * removed long opts * restructured to use functions * added changes from Mimi to work with new TSS * removed searching for TSS locations --- evmtest/README | 1 + evmtest/evmtest | 1 + evmtest/tests/boot_aggregate.sh | 140 ++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100755 evmtest/tests/boot_aggregate.sh diff --git a/evmtest/README b/evmtest/README index 91c8cda..b2d37e2 100644 --- a/evmtest/README +++ b/evmtest/README @@ -36,6 +36,7 @@ OPTIONS TEST NAMES ---------- + boot_aggregate - verify the IMA boot-aggregate env_validate - verify kernel build example_test - example test policy_sig - verify loading IMA policies diff --git a/evmtest/evmtest b/evmtest/evmtest index cd5e238..3c967f9 100755 --- a/evmtest/evmtest +++ b/evmtest/evmtest @@ -26,6 +26,7 @@ usage (){ # Any test should be added here manually # The reason this is manual is to prevent the accidental / malicious # placement of a script in tests/ + echo "[R] boot_aggregate" echo "[R] env_validate" echo "[ ] examples_test" echo "[R] kexec_sig" diff --git a/evmtest/tests/boot_aggregate.sh b/evmtest/tests/boot_aggregate.sh new file mode 100755 index 0000000..adecfeb --- /dev/null +++ b/evmtest/tests/boot_aggregate.sh @@ -0,0 +1,140 @@ +#!/bin/bash +# Author: David Jacobson <davidj@xxxxxxxxxxxxx> +TEST="boot_aggregate" + +ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/.." +source "$ROOT"/files/common.sh + +VERBOSE=0 +TPM_VERSION="2.0" +# This test validates the eventlog against the hardware PCRs in the TPM, and +# the boot aggregate against IMA. + +usage (){ + echo "boot_aggregate [-hv]" + echo "" + echo " This test must be run as root" + echo "" + echo " This test validates PCRs 0-7 in the TPM" + echo " It also validates the boot_aggregate based those PCRs" + echo " against what IMA has recorded" + echo "" + echo " -h Display this help message" + echo " -v Verbose logging" +} + +parse_args () { + TEMP=$(getopt -o 'hv' -n 'boot_aggregate' -- "$@") + eval set -- "$TEMP" + + while true ; do + case "$1" in + -h) usage; exit; shift;; + -v) VERBOSE=1; shift;; + --) shift; break;; + *) echo "[*] Unrecognized option $1"; exit 1 ;; + esac + done +} + +check_requirements () { + v_out "Checking if securityfs is mounted..." + if [ -z "$EVMTEST_SECFS_EXISTS" ]; then + fail "securityfs not found..." + fi + + v_out "Verifying TPM is present..." + if [ ! -d "$EVMTEST_SECFS/tpm0" ]; then + fail "Could not locate TPM in $EVMTEST_SECFS" + fi + + v_out "TPM found..." + + v_out "Checking if system supports reading event log..." + + if [ ! -f "$EVMTEST_SECFS"/tpm0/binary_bios_measurements ]; then + fail "Kernel does not support reading BIOS measurements, + please update to at least 4.16.0" + fi + + v_out "Verifying TPM Version" + if [ -e /sys/class/tpm/tpm0/device/caps ]; then + TPM_VERSION="1.2" + fi +} + +check_pcrs () { + v_out "Grabbing PCR values..." + local pcrs=() # array to store the Hardware PCR values + local sim_pcrs=() # What PCRs should be according to the event log + local eventextend=tsseventextend + local pcrread="tsspcrread -halg sha1" + local eventlog=/sys/kernel/security/tpm0/binary_bios_measurements + + if [ "$TPM_VERSION" == "1.2" ]; then + eventextend=tss1eventextend + pcrread=tss1pcrread + fi + + for ((i=0; i<=7; i++)); do + pcrs[i]=$(TPM_INTERFACE_TYPE=dev $pcrread -ha "$i" -ns) + done + + local output=$(mktemp -u) + "$eventextend" -if "$eventlog" -sim -ns > "$output" + + # Some PTT's are using TPM 1.2 event log format. Retry on failure. + if [ $? -ne 0 ]; then + eventextend=tss1eventextend + "$eventextend" -if "$eventlog" -sim -ns > "$output" + fi + + IFS=$'\n' read -d '' -r -a lines < "$output" + rm "$output" + + for line in "${lines[@]}" + do + : + sim_pcrs+=( "$(echo "$line" | cut -d ':' -f2 | \ + tr -d '[:space:]')" ) + if printf '%s' "$line" | grep -E -q "boot aggregate"; then + tss_agg=$(echo "$line" | cut -d ':' -f2 | \ + tr -d '[:space:]') + fi + done + + v_out "Validating PCRs.." + for ((i=0; i<=7; i++)); do + v_out "SIM PCR [$i]: ${sim_pcrs[$i]}" + v_out "TPM PCR [$i]: ${pcrs[$i]}" + if [ "${pcrs[$i]}" != "${sim_pcrs[$i]}" ]; then + v_out "PCRs are incorrect..." + fail "Mismatch at PCR $i " + else + v_out "PCR $i validated..." + fi + done +} + +check_boot_aggregate () { + v_out "Validating Boot Aggregate..." + ima_agg=$(grep boot_aggregate \ + "$EVMTEST_SECFS"/ima/ascii_runtime_measurements| head -1 | cut \ + -d ":" -f2|cut -d " " -f1) + v_out "TSS BOOT AGG: $tss_agg" + v_out "IMA BOOT AGG: $ima_agg" + + if [ "$tss_agg" != "$ima_agg" ]; then + fail "Boot Aggregate is inconsistent" + else + v_out "Boot Aggregate validated" + fi +} + +EVMTEST_require_root +echo "[*] Starting test: $TEST" +parse_args "$@" +check_requirements +check_pcrs +check_boot_aggregate +passed -- 2.20.1