1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2020 Microsoft Corporation 4# Copyright (c) 2020-2021 Petr Vorel <pvorel@suse.cz> 5# Author: Lachlan Sneff <t-josne@linux.microsoft.com> 6# 7# Verify that keys are measured correctly based on policy. 8 9TST_NEEDS_CMDS="cmp cut grep sed" 10TST_CNT=2 11TST_SETUP=setup 12TST_CLEANUP=cleanup 13TST_MIN_KVER="5.6" 14 15FUNC_KEYCHECK='func=KEY_CHECK' 16REQUIRED_POLICY="^measure.*$FUNC_KEYCHECK" 17 18setup() 19{ 20 require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt 21 require_valid_policy_template 22} 23 24cleanup() 25{ 26 tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID 27} 28 29require_valid_policy_template() 30{ 31 while read line; do 32 if echo $line | grep -q 'template=' && ! echo $line | grep -q 'template=ima-buf'; then 33 tst_brk TCONF "only template=ima-buf can be specified for KEY_CHECK" 34 fi 35 done < $TST_TMPDIR/policy.txt 36} 37 38check_keys_policy() 39{ 40 local pattern="$1" 41 42 if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then 43 tst_res TCONF "IMA policy must specify $pattern, $FUNC_KEYCHECK" 44 return 1 45 fi 46 return 0 47} 48 49# Based on https://lkml.org/lkml/2019/12/13/564. 50# (450d0fd51564 - "IMA: Call workqueue functions to measure queued keys") 51test1() 52{ 53 local keycheck_lines i keyrings templates 54 local pattern='keyrings=[^[:space:]]+' 55 local test_file="file.txt" tmp_file="file2.txt" 56 57 tst_res TINFO "verify key measurement for keyrings and templates specified in IMA policy" 58 59 check_keys_policy "$pattern" > $tmp_file || return 60 keycheck_lines=$(cat $tmp_file) 61 keyrings=$(for i in $keycheck_lines; do echo "$i" | grep "keyrings" | \ 62 sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') 63 if [ -z "$keyrings" ]; then 64 tst_res TCONF "IMA policy has a keyring key-value specifier, but no specified keyrings" 65 return 66 fi 67 68 templates=$(for i in $keycheck_lines; do echo "$i" | grep "template" | \ 69 cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') 70 71 tst_res TINFO "keyrings: '$keyrings'" 72 tst_res TINFO "templates: '$templates'" 73 74 grep -E "($templates).*($keyrings)" $ASCII_MEASUREMENTS | while read line 75 do 76 local digest expected_digest algorithm 77 78 digest=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f2) 79 algorithm=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f1) 80 keyring=$(echo "$line" | cut -d' ' -f5) 81 82 echo "$line" | cut -d' ' -f6 | tst_hexdump -d > $test_file 83 84 if ! expected_digest="$(compute_digest $algorithm $test_file)"; then 85 tst_res TCONF "cannot compute digest for $algorithm" 86 return 87 fi 88 89 if [ "$digest" != "$expected_digest" ]; then 90 tst_res TFAIL "incorrect digest was found for $keyring keyring" 91 return 92 fi 93 done 94 95 tst_res TPASS "specified keyrings were measured correctly" 96} 97 98# Create a new keyring, import a certificate into it, and verify 99# that the certificate is measured correctly by IMA. 100test2() 101{ 102 tst_require_cmds keyctl openssl 103 104 require_evmctl "1.3.2" 105 106 local cert_file="$TST_DATAROOT/x509_ima.der" 107 local keyring_name="key_import_test" 108 local pattern="keyrings=[^[:space:]]*$keyring_name" 109 local temp_file="file.txt" 110 111 tst_res TINFO "verify measurement of certificate imported into a keyring" 112 113 check_keys_policy "$pattern" >/dev/null || return 114 115 KEYRING_ID=$(keyctl newring $keyring_name @s) || \ 116 tst_brk TBROK "unable to create a new keyring" 117 118 if ! tst_is_num $KEYRING_ID; then 119 tst_brk TBROK "unable to parse the new keyring id ('$KEYRING_ID')" 120 fi 121 122 evmctl import $cert_file $KEYRING_ID > /dev/null || \ 123 tst_brk TBROK "unable to import a certificate into $keyring_name keyring" 124 125 grep $keyring_name $ASCII_MEASUREMENTS | tail -n1 | cut -d' ' -f6 | \ 126 tst_hexdump -d > $temp_file 127 128 if [ ! -s $temp_file ]; then 129 tst_res TFAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS" 130 return 131 fi 132 133 if ! openssl x509 -in $temp_file -inform der > /dev/null; then 134 tst_res TFAIL "logged certificate is not a valid x509 certificate" 135 return 136 fi 137 138 if cmp -s $temp_file $cert_file; then 139 tst_res TPASS "logged certificate matches the original" 140 else 141 tst_res TFAIL "logged certificate does not match original" 142 fi 143} 144 145. ima_setup.sh 146tst_run 147