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