From patchwork Tue Feb 23 22:59:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vorel X-Patchwork-Id: 1443667 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DlZHz4S4jz9sVF for ; Wed, 24 Feb 2021 09:59:43 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 3B4C23C601E for ; Tue, 23 Feb 2021 23:59:41 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-5.smtp.seeweb.it (in-5.smtp.seeweb.it [IPv6:2001:4b78:1:20::5]) by picard.linux.it (Postfix) with ESMTP id 047D03C2BEF for ; Tue, 23 Feb 2021 23:59:38 +0100 (CET) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by in-5.smtp.seeweb.it (Postfix) with ESMTPS id 75B67600705 for ; Tue, 23 Feb 2021 23:59:38 +0100 (CET) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id DCF81AF45; Tue, 23 Feb 2021 22:59:37 +0000 (UTC) From: Petr Vorel To: ltp@lists.linux.it Date: Tue, 23 Feb 2021 23:59:29 +0100 Message-Id: <20210223225930.27095-2-pvorel@suse.cz> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210223225930.27095-1-pvorel@suse.cz> References: <20210223225930.27095-1-pvorel@suse.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-5.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.0 required=7.0 tests=SPF_HELO_NONE,SPF_PASS autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-5.smtp.seeweb.it Subject: [LTP] [PATCH v3 1/2] IMA: Generalize key measurement tests X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: snitzer@redhat.com, Lakshmi Ramasubramanian , dm-devel@redhat.com, Tushar Sugandhi , linux-integrity@vger.kernel.org, Mimi Zohar , gmazyland@gmail.com, agk@redhat.com Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" From: Tushar Sugandhi Refactor check_keys_policy() and test1() implemented in ima_keys.sh to make it generic, and move the functionality to ima_setup.sh, to be used for measurements in other tests in the future. Suggested-by: Petr Vorel Reviewed-by: Petr Vorel Signed-off-by: Tushar Sugandhi [ pvorel: move tst_res TPASS/TFAIL into test_policy_measurement(), further cleanup ] Signed-off-by: Petr Vorel --- .../security/integrity/ima/tests/ima_keys.sh | 58 ++--------------- .../security/integrity/ima/tests/ima_setup.sh | 62 +++++++++++++++++++ 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh index c9eef4b68..1aeb1cd89 100755 --- a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh @@ -6,7 +6,7 @@ # # Verify that keys are measured correctly based on policy. -TST_NEEDS_CMDS="cmp cut grep sed xxd" +TST_NEEDS_CMDS="cmp cut grep tail xxd" TST_CNT=2 TST_NEEDS_DEVICE=1 TST_SETUP=setup @@ -28,64 +28,18 @@ cleanup() tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID } -check_keys_policy() -{ - local pattern="$1" - - if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then - tst_res TCONF "IMA policy must specify $pattern, $FUNC_KEYCHECK, $TEMPLATE_BUF" - return 1 - fi - return 0 -} - # Based on https://lkml.org/lkml/2019/12/13/564. # (450d0fd51564 - "IMA: Call workqueue functions to measure queued keys") test1() { local keycheck_lines i keyrings templates local pattern='keyrings=[^[:space:]]+' - local test_file="file.txt" tmp_file="file2.txt" + local temp_file="test1.txt" tst_res TINFO "verify key measurement for keyrings and templates specified in IMA policy" - check_keys_policy "$pattern" > $tmp_file || return - keycheck_lines=$(cat $tmp_file) - keyrings=$(for i in $keycheck_lines; do echo "$i" | grep "keyrings" | \ - sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') - if [ -z "$keyrings" ]; then - tst_res TCONF "IMA policy has a keyring key-value specifier, but no specified keyrings" - return - fi - - templates=$(for i in $keycheck_lines; do echo "$i" | grep "template" | \ - cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') - - tst_res TINFO "keyrings: '$keyrings'" - tst_res TINFO "templates: '$templates'" - - grep -E "($templates).*($keyrings)" $ASCII_MEASUREMENTS | while read line - do - local digest expected_digest algorithm - - digest=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f2) - algorithm=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f1) - keyring=$(echo "$line" | cut -d' ' -f5) - - echo "$line" | cut -d' ' -f6 | xxd -r -p > $test_file - - if ! expected_digest="$(compute_digest $algorithm $test_file)"; then - tst_res TCONF "cannot compute digest for $algorithm" - return - fi - - if [ "$digest" != "$expected_digest" ]; then - tst_res TFAIL "incorrect digest was found for $keyring keyring" - return - fi - done - - tst_res TPASS "specified keyrings were measured correctly" + check_policy_pattern "$pattern" $FUNC_KEYCHECK $TEMPLATE_BUF > $temp_file || return + test_policy_measurement keyrings $temp_file } # Create a new keyring, import a certificate into it, and verify @@ -97,11 +51,11 @@ test2() local cert_file="$TST_DATAROOT/x509_ima.der" local keyring_name="key_import_test" local pattern="keyrings=[^[:space:]]*$keyring_name" - local temp_file="file.txt" + local temp_file="test2.txt" tst_res TINFO "verify measurement of certificate imported into a keyring" - check_keys_policy "$pattern" >/dev/null || return + check_policy_pattern "$pattern" $FUNC_KEYCHECK $TEMPLATE_BUF >/dev/null || return KEYRING_ID=$(keyctl newring $keyring_name @s) || \ tst_brk TBROK "unable to create a new keyring" diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh index 59a7ffeac..605db0ff6 100644 --- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh @@ -54,6 +54,19 @@ compute_digest() return 1 } +check_policy_pattern() +{ + local pattern="$1" + local func="$2" + local template="$3" + + if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then + tst_res TCONF "IMA policy must specify $pattern, $func, $template" + return 1 + fi + return 0 +} + check_policy_readable() { if [ ! -f $IMA_POLICY ]; then @@ -269,6 +282,55 @@ get_algorithm_digest() echo "$algorithm|$digest" } +test_policy_measurement() +{ + local policy_option="$1" + local lines=$(cat $2) + local input_digest="$3" + local test_file="$TST_TMPDIR/test.txt" + local grep_file="$TST_TMPDIR/grep.txt" + local i sources templates + + tst_require_cmds cut sed xxd + + sources=$(for i in $lines; do echo "$i" | grep "$policy_option" | \ + sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') + if [ -z "$sources" ]; then + tst_res TCONF "IMA policy $policy_option is a key-value specifier, but no values specified" + return + fi + + templates=$(for i in $lines; do echo "$i" | grep "template" | \ + cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g') + + tst_res TINFO "policy sources: '$sources'" + tst_res TINFO "templates: '$templates'" + + grep -E "($templates).*($sources)" $ASCII_MEASUREMENTS > $grep_file + + while read line; do + local algorithm digest expected_digest src_line + + digest=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f2) + algorithm=$(echo "$line" | cut -d' ' -f4 | cut -d':' -f1) + src_line=$(echo "$line" | cut -d' ' -f5) + + echo "$line" | cut -d' ' -f6 | xxd -r -p > $test_file + + if ! expected_digest="$(compute_digest $algorithm $test_file)"; then + tst_res TCONF "cannot compute digest for $algorithm" + return + fi + + if [ "$digest" != "$expected_digest" ]; then + tst_res TFAIL "incorrect digest was found for $src_line $policy_option" + return + fi + done < $grep_file + + tst_res TPASS "$policy_option measured correctly" +} + # loop device is needed to use only for tmpfs TMPDIR="${TMPDIR:-/tmp}" if [ "$(df -T $TMPDIR | tail -1 | awk '{print $2}')" != "tmpfs" -a -n "$TST_NEEDS_DEVICE" ]; then From patchwork Tue Feb 23 22:59:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vorel X-Patchwork-Id: 1443668 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DlZJ83WSwz9sVF for ; Wed, 24 Feb 2021 09:59:52 +1100 (AEDT) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id E42143C60C8 for ; Tue, 23 Feb 2021 23:59:49 +0100 (CET) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [217.194.8.3]) by picard.linux.it (Postfix) with ESMTP id 269313C5A06 for ; Tue, 23 Feb 2021 23:59:39 +0100 (CET) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by in-3.smtp.seeweb.it (Postfix) with ESMTPS id 9078A1A01013 for ; Tue, 23 Feb 2021 23:59:38 +0100 (CET) Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 28362AF49; Tue, 23 Feb 2021 22:59:38 +0000 (UTC) From: Petr Vorel To: ltp@lists.linux.it Date: Tue, 23 Feb 2021 23:59:30 +0100 Message-Id: <20210223225930.27095-3-pvorel@suse.cz> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210223225930.27095-1-pvorel@suse.cz> References: <20210223225930.27095-1-pvorel@suse.cz> MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.102.4 at in-3.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.0 required=7.0 tests=SPF_HELO_NONE,SPF_PASS autolearn=disabled version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on in-3.smtp.seeweb.it Subject: [LTP] [PATCH v3 2/2] IMA: Add test for dm-crypt measurement X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: snitzer@redhat.com, Lakshmi Ramasubramanian , dm-devel@redhat.com, Tushar Sugandhi , linux-integrity@vger.kernel.org, Mimi Zohar , gmazyland@gmail.com, agk@redhat.com Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" From: Tushar Sugandhi New functionality is being added to IMA to measure data provided by kernel components. With this feature, IMA policy can be set to enable measuring data provided by device-mapper targets. Currently one such device-mapper target - dm-crypt, is being updated to use this functionality. This new functionality needs test automation in LTP. Add a testcase which verifies that the IMA subsystem correctly measures the data coming from a device-mapper target - dm-crypt. Reviewed-by: Petr Vorel Signed-off-by: Tushar Sugandhi [ pvorel: adapt to previous commit changes, removed template=ima-buf, further cleanup ] Signed-off-by: Petr Vorel --- I wonder if $input_digest and $input_digest_found is needed to be considered in loop. Maybe there could be return after first check when $input_digest is passed to test_policy_measurement(). runtest/ima | 1 + .../kernel/security/integrity/ima/README.md | 20 +++++++++ .../integrity/ima/tests/ima_dm_crypt.sh | 41 +++++++++++++++++++ .../security/integrity/ima/tests/ima_setup.sh | 11 ++++- 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100755 testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh diff --git a/runtest/ima b/runtest/ima index 5f4b4a7a1..123b6c8b0 100644 --- a/runtest/ima +++ b/runtest/ima @@ -5,4 +5,5 @@ ima_tpm ima_tpm.sh ima_violations ima_violations.sh ima_keys ima_keys.sh ima_kexec ima_kexec.sh +ima_dm_crypt ima_dm_crypt.sh evm_overlay evm_overlay.sh diff --git a/testcases/kernel/security/integrity/ima/README.md b/testcases/kernel/security/integrity/ima/README.md index 68d046678..007662fae 100644 --- a/testcases/kernel/security/integrity/ima/README.md +++ b/testcases/kernel/security/integrity/ima/README.md @@ -37,6 +37,26 @@ see example in `kexec.policy`. The test attempts to kexec the existing running kernel image. To kexec a different kernel image export `IMA_KEXEC_IMAGE=`. +### IMA DM target (dm-crypt) measurement test + +To enable IMA to measure device-mapper target - dm-crypt, +`ima_dm_crypt.sh` requires a readable IMA policy, as well as +a loaded measure policy with +`func=CRITICAL_DATA data_sources=dm-crypt` + +As well as what's required for the IMA tests, dm-crypt measurement test require +reading the IMA policy allowed in the kernel configuration: +``` +CONFIG_IMA_READ_POLICY=y +``` + +The following kernel configuration is also required. It enables compiling +the device-mapper target module dm-crypt, which allows to create a device +that transparently encrypts the data on it. +``` +CONFIG_DM_CRYPT +``` + ## EVM tests `evm_overlay.sh` requires a builtin IMA appraise tcb policy (e.g. `ima_policy=appraise_tcb` diff --git a/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh b/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh new file mode 100755 index 000000000..b49662f73 --- /dev/null +++ b/testcases/kernel/security/integrity/ima/tests/ima_dm_crypt.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2021 Microsoft Corporation +# Copyright (c) 2021 Petr Vorel +# Author: Tushar Sugandhi +# +# Verify that DM target dm-crypt are measured correctly based on policy. + +TST_NEEDS_CMDS="dmsetup" +TST_NEEDS_DEVICE=1 +TST_SETUP=setup +TST_CLEANUP=cleanup + +. ima_setup.sh + +FUNC='func=CRITICAL_DATA' +PATTERN='data_sources=[^[:space:]]+' +REQUIRED_POLICY="^measure.*($FUNC.*$PATTERN|$PATTERN.*$FUNC)" + +setup() +{ + require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt +} + +cleanup() +{ + ROD "dmsetup remove test-crypt" +} + +test1() +{ + local input_digest="039d8ff71918608d585adca3e5aab2e3f41f84d6" + local key="faf453b4ee938cff2f0d2c869a0b743f59125c0a37f5bcd8f1dbbd911a78abaa" + + tst_res TINFO "verifying dm-crypt target measurement" + + ROD dmsetup create test-crypt --table "0 1953125 crypt aes-xts-plain64 $key 0 /dev/loop0 0 1 allow_discards" + check_policy_measurement data_sources $TST_TMPDIR/policy.txt $input_digest +} + +tst_run diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh index 605db0ff6..22bb4649d 100644 --- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh +++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh @@ -289,7 +289,7 @@ test_policy_measurement() local input_digest="$3" local test_file="$TST_TMPDIR/test.txt" local grep_file="$TST_TMPDIR/grep.txt" - local i sources templates + local i input_digest_found sources templates tst_require_cmds cut sed xxd @@ -326,8 +326,17 @@ test_policy_measurement() tst_res TFAIL "incorrect digest was found for $src_line $policy_option" return fi + + if [ "$input_digest" -a "$digest" = "$input_digest" ]; then + input_digest_found=1 + fi done < $grep_file + if [ "$input_digest" -a "$input_digest_found" != 1 ]; then + tst_res TFAIL "expected digest '$input_digest' not found" + return + fi + tst_res TPASS "$policy_option measured correctly" }