From patchwork Fri Jun 16 19:23:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13283229 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21248EB64D7 for ; Fri, 16 Jun 2023 19:27:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346134AbjFPT1c (ORCPT ); Fri, 16 Jun 2023 15:27:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346177AbjFPT1L (ORCPT ); Fri, 16 Jun 2023 15:27:11 -0400 Received: from frasgout12.his.huawei.com (unknown [14.137.139.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2138E4498 for ; Fri, 16 Jun 2023 12:25:30 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.227]) by frasgout12.his.huawei.com (SkyGuard) with ESMTP id 4QjTLZ40slz9xFbH for ; Sat, 17 Jun 2023 03:12:22 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwAH2F7TtoxksMlFAw--.17356S3; Fri, 16 Jun 2023 20:24:14 +0100 (CET) From: Roberto Sassu To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com Cc: linux-integrity@vger.kernel.org, vt@altlinux.org, pvorel@suse.cz, stefanb@linux.ibm.com, paul@paul-moore.com, casey@schaufler-ca.com, Roberto Sassu Subject: [PATCH v3 ima-evm-utils 1/4] Include the filesystem UUID in HMAC calculation Date: Fri, 16 Jun 2023 21:23:55 +0200 Message-Id: <20230616192358.314906-2-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> References: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwAH2F7TtoxksMlFAw--.17356S3 X-Coremail-Antispam: 1UD129KBjvJXoWxJry3ur45Ar45Xw1fZryrZwb_yoW8Cw1kpa 9ag345ta4ktF1xKFy3Aa1xua4rJ3y0yr13KwsrZw13ZasxWFWjqa4fKF4Yga45Xr1kAFyf Xw4akryF9ayDA3DanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBFb4IE77IF4wAFF20E14v26ryj6rWUM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUGw A2048vs2IY020Ec7CjxVAFwI0_JFI_Gr1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUCVW8JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2 WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkE bVWUJVW8JwACjcxG0xvY0x0EwIxGrwCY1x0262kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwI xGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480 Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7 IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x 0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x07j-pnQUUUUU= X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgAKBF1jj4rIbAAAsT X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Roberto Sassu Modify calc_evm_hmac() to include, similarly to calc_evm_hash(), the filesystem UUID in the HMAC calculation. If the -u option is not specified in the evmctl command line, the UUID of the filesystem the input file resides on is taken for the calculation. If a string is specified as a value for the -u option, that string is taken as UUID (assuming that it is formatted correctly). If no value is specified for the -u option, the filesystem UUID is not included in the HMAC calculation. Not including the filesystem UUID in the digest/HMAC calculation is needed for the case where the kernel is compiled with CONFIG_EVM_ATTR_FSUUID=n, or the digest/HMAC is not for an EVM portable signature. Fixes: 1d24a94bb556 ("added uuid support for EVM") Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger --- src/evmctl.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/evmctl.c b/src/evmctl.c index c35a28c58f4..c24261cf0e6 100644 --- a/src/evmctl.c +++ b/src/evmctl.c @@ -1199,6 +1199,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *s int keylen; unsigned char evmkey[MAX_KEY_SIZE]; char list[1024]; + char uuid[16]; ssize_t list_size; struct h_misc_64 hmac_misc; int hmac_size; @@ -1330,6 +1331,18 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *s log_err("EVP_DigestSignUpdate() failed\n"); goto out_ctx_cleanup; } + if (!(hmac_flags & HMAC_FLAG_NO_UUID)) { + err = get_uuid(&st, uuid); + if (err) + goto out_ctx_cleanup; + + err = EVP_DigestSignUpdate(pctx, (const unsigned char *)uuid, + sizeof(uuid)); + if (!err) { + log_err("EVP_DigestSignUpdate() failed\n"); + goto out_ctx_cleanup; + } + } err = EVP_DigestSignFinal(pctx, sig, &siglen); if (err != 1) log_err("EVP_DigestSignFinal() failed\n"); From patchwork Fri Jun 16 19:23:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13283231 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5E175EB64D7 for ; Fri, 16 Jun 2023 19:27:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345886AbjFPT1q (ORCPT ); Fri, 16 Jun 2023 15:27:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346149AbjFPT1d (ORCPT ); Fri, 16 Jun 2023 15:27:33 -0400 Received: from frasgout13.his.huawei.com (unknown [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E686D4697 for ; Fri, 16 Jun 2023 12:25:51 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.229]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4QjTNS717mz9y8JV for ; Sat, 17 Jun 2023 03:14:00 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwAH2F7TtoxksMlFAw--.17356S4; Fri, 16 Jun 2023 20:24:19 +0100 (CET) From: Roberto Sassu To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com Cc: linux-integrity@vger.kernel.org, vt@altlinux.org, pvorel@suse.cz, stefanb@linux.ibm.com, paul@paul-moore.com, casey@schaufler-ca.com, Roberto Sassu Subject: [PATCH v3 ima-evm-utils 2/4] Restore correct HMAC calculation for directories Date: Fri, 16 Jun 2023 21:23:56 +0200 Message-Id: <20230616192358.314906-3-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> References: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwAH2F7TtoxksMlFAw--.17356S4 X-Coremail-Antispam: 1UD129KBjvJXoWrZF1DJFWkAw4fZr4Utr4DCFg_yoW8Jr4kpa 1UWw1fGFZ5Kr17GFn3tFsrX343WaykWa15XF4kCw15CwnxuFn8KF1xtF43Xas3Jr4rJrWY v3ZIgryUXa1DA3JanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBFb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUXw A2048vs2IY020Ec7CjxVAFwI0_Gr0_Xr1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUCVW8JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2 WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkE bVWUJVW8JwACjcxG0xvY0x0EwIxGrwCY1x0262kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwI xGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480 Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7 IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x 0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x07jga9-UUUUU= X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgAKBF1jj4rIbAABsS X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Roberto Sassu Commit 6ecb88352886 ("evmctl: Remove left-over check S_ISDIR() for directory signing") removes fetching the inode generation for directories. While directories might not be signed, EVM currently calculates the HMAC on them, including the inode generation. To keep user space and kernel space aligned, reenable fetching the inode generation for directories, and add again the comment that the inode generation cannot be obtained for special files. Fixes: Commit 6ecb88352886 ("evmctl: Remove left-over check S_ISDIR() for directory signing") Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger --- src/evmctl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/evmctl.c b/src/evmctl.c index c24261cf0e6..7a3ffd7c823 100644 --- a/src/evmctl.c +++ b/src/evmctl.c @@ -1229,7 +1229,11 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *s goto out; } - if (S_ISREG(st.st_mode)) { + if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode)) { + /* + * We cannot at the moment get generation of special files.. + * kernel API does not support it. + */ int fd = open(file, 0); if (fd < 0) { From patchwork Fri Jun 16 19:23:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13283230 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09241EB64D7 for ; Fri, 16 Jun 2023 19:27:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346230AbjFPT1g (ORCPT ); Fri, 16 Jun 2023 15:27:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346234AbjFPT1V (ORCPT ); Fri, 16 Jun 2023 15:27:21 -0400 Received: from frasgout11.his.huawei.com (unknown [14.137.139.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEF4B44AA for ; Fri, 16 Jun 2023 12:25:35 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.228]) by frasgout11.his.huawei.com (SkyGuard) with ESMTP id 4QjTNW4b64z9xFQY for ; Sat, 17 Jun 2023 03:14:03 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwAH2F7TtoxksMlFAw--.17356S5; Fri, 16 Jun 2023 20:24:24 +0100 (CET) From: Roberto Sassu To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com Cc: linux-integrity@vger.kernel.org, vt@altlinux.org, pvorel@suse.cz, stefanb@linux.ibm.com, paul@paul-moore.com, casey@schaufler-ca.com, Roberto Sassu Subject: [PATCH v3 ima-evm-utils 3/4] Add --hmackey option for evmctl Date: Fri, 16 Jun 2023 21:23:57 +0200 Message-Id: <20230616192358.314906-4-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> References: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwAH2F7TtoxksMlFAw--.17356S5 X-Coremail-Antispam: 1UD129KBjvJXoWxZw4rtry5Ar1rWF13Xr13urg_yoW5tF43pa 98J345JryktF17Jrn8GF1kt3W7Can3ur13tr47Wws7uF98XF92gFs3Kr1F9rW3ZFWrtFy3 ZrWIqFWfWa9rGrDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUBFb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF04k2 6cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUWw A2048vs2IY020Ec7CjxVAFwI0_Xr0E3s1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxS w2x7M28EF7xvwVC0I7IYx2IY67AKxVWUCVW8JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxV W8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_Gr0_Cr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2 WlYx0E2Ix0cI8IcVAFwI0_JrI_JrylYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkE bVWUJVW8JwACjcxG0xvY0x0EwIxGrwCY1x0262kKe7AKxVW8ZVWrXwCF04k20xvY0x0EwI xGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480 Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7 IYx2IY67AKxVWUCVW8JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr1j6F4UJwCI42IY6xAI w20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x 0267AKxVW8Jr0_Cr1UYxBIdaVFxhVjvjDU0xZFpf9x07jIBT5UUUUU= X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAgAKBF1jj4rIbAACsR X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Roberto Sassu "evmctl --hmac" was only enabled in debug mode, since the hmac key was not exposed to userspace. It was never really used. With the ability of creating an encrypted key based on user-provided decrypted data, verifying the EVM hmac is now feasible. Make "evmctl --hmac" more configurable by adding the --hmackey option, to specify an alternate path for the file containing the HMAC key. By default evmctl looks in /etc/keys/evm-key-plain. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger --- README | 3 ++- src/evmctl.c | 12 ++++++++++-- src/imaevm.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README b/README index 40a61f94315..7239dda257e 100644 --- a/README +++ b/README @@ -40,7 +40,7 @@ COMMANDS ima_fix [-t fdsxm] path ima_clear [-t fdsxm] path sign_hash [--veritysig] [--key key] [--pass=] - hmac [--imahash | --imasig ] file + hmac [--imahash | --imasig] [--hmackey key] file OPTIONS @@ -82,6 +82,7 @@ OPTIONS --ignore-violations ignore ToMToU measurement violations --verify-sig verify the file signature based on the file hash, both stored in the template data. + --hmackey path to symmetric key (default: /etc/keys/evm-key-plain) -v increase verbosity level -h, --help display this help and exit diff --git a/src/evmctl.c b/src/evmctl.c index 7a3ffd7c823..8caf9bd83fb 100644 --- a/src/evmctl.c +++ b/src/evmctl.c @@ -1417,7 +1417,8 @@ static int cmd_hmac_evm(struct command *cmd) return err; } - return hmac_evm(file, "/etc/keys/evm-key-plain"); + return hmac_evm(file, imaevm_params.hmackeyfile ? : + "/etc/keys/evm-key-plain"); } static int ima_fix(const char *path) @@ -2873,6 +2874,9 @@ static void usage(void) " --engine e preload OpenSSL engine e (such as: gost) is deprecated\n" #endif " --ignore-violations ignore ToMToU measurement violations\n" +#ifdef DEBUG + " --hmackey path to symmetric key (default: /etc/keys/evm-key-plain)\n" +#endif " -v increase verbosity level\n" " -h, --help display this help and exit\n" "\n" @@ -2902,7 +2906,7 @@ struct command cmds[] = { {"ima_clear", cmd_ima_clear, 0, "[-t fdsxm] path", "Recursively remove IMA/EVM xattrs.\n"}, {"sign_hash", cmd_sign_hash, 0, "[--veritysig] [--key key] [--pass[=]]", "Sign hashes from either shaXsum or \"fsverity digest\" output.\n"}, #ifdef DEBUG - {"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig ] file", "Sign file metadata with HMAC using symmetric key (for testing purpose).\n"}, + {"hmac", cmd_hmac_evm, 0, "[--imahash | --imasig] [--hmackey key] file", "Sign file metadata with HMAC using symmetric key (for testing purpose).\n"}, #endif {0, 0, 0, NULL} }; @@ -2944,6 +2948,7 @@ static struct option opts[] = { {"keyid-from-cert", 1, 0, 145}, {"veritysig", 0, 0, 146}, {"hwtpm", 0, 0, 147}, + {"hmackey", 1, 0, 148}, {} }; @@ -3189,6 +3194,9 @@ int main(int argc, char *argv[]) case 147: hwtpm = 1; break; + case 148: + imaevm_params.hmackeyfile = optarg; + break; case '?': exit(1); break; diff --git a/src/imaevm.h b/src/imaevm.h index 78e7ed5e89d..18d7b0e447e 100644 --- a/src/imaevm.h +++ b/src/imaevm.h @@ -221,6 +221,7 @@ struct libimaevm_params { const char *keypass; uint32_t keyid; /* keyid overriding value, unless 0. (Host order.) */ ENGINE *eng; + const char *hmackeyfile; }; struct RSA_ASN1_template { From patchwork Fri Jun 16 19:23:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 13283235 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D4A9EB64D8 for ; Fri, 16 Jun 2023 19:41:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344544AbjFPTlL (ORCPT ); Fri, 16 Jun 2023 15:41:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343594AbjFPTlK (ORCPT ); Fri, 16 Jun 2023 15:41:10 -0400 Received: from frasgout13.his.huawei.com (unknown [14.137.139.46]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ECA3D119 for ; Fri, 16 Jun 2023 12:41:07 -0700 (PDT) Received: from mail02.huawei.com (unknown [172.18.147.227]) by frasgout13.his.huawei.com (SkyGuard) with ESMTP id 4QjTNf5mt9z9xFGj for ; Sat, 17 Jun 2023 03:14:10 +0800 (CST) Received: from huaweicloud.com (unknown [10.204.63.22]) by APP2 (Coremail) with SMTP id GxC2BwAH2F7TtoxksMlFAw--.17356S6; Fri, 16 Jun 2023 20:24:29 +0100 (CET) From: Roberto Sassu To: zohar@linux.ibm.com, dmitry.kasatkin@gmail.com Cc: linux-integrity@vger.kernel.org, vt@altlinux.org, pvorel@suse.cz, stefanb@linux.ibm.com, paul@paul-moore.com, casey@schaufler-ca.com, Roberto Sassu Subject: [PATCH v3 ima-evm-utils 4/4] Add simple tests to check EVM HMAC calculation Date: Fri, 16 Jun 2023 21:23:58 +0200 Message-Id: <20230616192358.314906-5-roberto.sassu@huaweicloud.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> References: <20230616192358.314906-1-roberto.sassu@huaweicloud.com> MIME-Version: 1.0 X-CM-TRANSID: GxC2BwAH2F7TtoxksMlFAw--.17356S6 X-Coremail-Antispam: 1UD129KBjvAXoW3tFy5Aw1rArWrWF1rXw4DCFg_yoW8JFy8Ko WxGrW3tw40gr13Arn5Zr4IyFZrCa93uF45ZrW2vw1qq3W3try8C345C34UJr4Yv3yrW3y8 Ga4kC348ZrWUKrsxn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYZ7kC6x804xWl14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK 8VAvwI8IcIk0rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF 0E3s1l82xGYIkIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vE j48ve4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxV AFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIE14v26r4j6F4UM28EF7xvwVC2z280aVCY1x02 67AKxVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVW8JVWxJwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4UJVWxJr1lIxAI cVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2js IEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjxUI9mRUUUUU X-CM-SenderInfo: purev21wro2thvvxqx5xdzvxpfor3voofrz/1tbiAQAKBF1jj47EOwAAsP X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Roberto Sassu Add a simple test to ensure that the kernel and evmctl provide the same result for the HMAC calculation. Do it with SELinux or Smack, whichever is available (if the UML kernel is used, the test is done with both LSMs). Also add another test to evaluate the HMAC on a directory for which Smack added the SMACK64TRANSMUTE xattr. The second test fails without the kernel patch 'smack: Set the SMACK64TRANSMUTE xattr in smack_inode_init_security()', as Smack uses __vfs_setxattr() to set SMACK64TRANSMUTE, which does not go through EVM, and makes the HMAC invalid. Require (unless the UML kernel is used) that the TST_EVM_CHANGE_MODE environment variable is set to 1, so that users acknowledge that they are initializing EVM with a well-known HMAC key, which can introduce obvious security concerns. Finally, enable SELinux, the EVM additional xattrs, and encrypted keys with user-decrypted data in the kernel configuration for CI, and set TST_EVM_CHANGE_MODE to 1 in the Github Action workflow. Signed-off-by: Roberto Sassu --- .github/workflows/ci.yml | 1 + kernel-configs/base | 6 +- kernel-configs/integrity | 1 + tests/Makefile.am | 2 +- tests/evm_hmac.test | 281 +++++++++++++++++++++++++++++++++++++++ tests/functions.sh | 6 + 6 files changed, 295 insertions(+), 2 deletions(-) create mode 100755 tests/evm_hmac.test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3dcf3dbc0a..54dbca5e5d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,6 +152,7 @@ jobs: TSS: ibmtss TST_ENV: um TST_KERNEL: ../linux + TST_EVM_CHANGE_MODE: 1 - container: "centos:7" env: diff --git a/kernel-configs/base b/kernel-configs/base index 7acbd5b3b2a..a3cec34bc58 100644 --- a/kernel-configs/base +++ b/kernel-configs/base @@ -46,11 +46,13 @@ CONFIG_TMPFS_XATTR=y CONFIG_CONFIGFS_FS=y CONFIG_KEYS=y CONFIG_ENCRYPTED_KEYS=y +CONFIG_USER_DECRYPTED_DATA=y CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_PATH=y -CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,bpf" +CONFIG_SECURITY_SMACK=y +CONFIG_LSM="lockdown,yama,loadpin,safesetid,selinux,smack,bpf" CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER2=y @@ -211,3 +213,5 @@ CONFIG_9P_FS_POSIX_ACL=y CONFIG_9P_FS_SECURITY=y CONFIG_ETHERNET=n CONFIG_WLAN=n +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_DEVELOP=y diff --git a/kernel-configs/integrity b/kernel-configs/integrity index a7e01e19466..2e104d205ba 100644 --- a/kernel-configs/integrity +++ b/kernel-configs/integrity @@ -27,3 +27,4 @@ CONFIG_EVM_ATTR_FSUUID=y CONFIG_EVM_ADD_XATTRS=y CONFIG_EVM_LOAD_X509=y CONFIG_EVM_X509_PATH="/etc/keys/x509_evm.der" +CONFIG_EVM_EXTRA_SMACK_XATTRS=y diff --git a/tests/Makefile.am b/tests/Makefile.am index 03aa5b76088..a28f671398f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,7 +3,7 @@ TESTS = $(check_SCRIPTS) check_SCRIPTS += ima_hash.test sign_verify.test boot_aggregate.test \ fsverity.test portable_signatures.test ima_policy_check.test \ - mmap_check.test + mmap_check.test evm_hmac.test check_PROGRAMS := test_mmap diff --git a/tests/evm_hmac.test b/tests/evm_hmac.test new file mode 100755 index 00000000000..fe0ee218dd0 --- /dev/null +++ b/tests/evm_hmac.test @@ -0,0 +1,281 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2023 Roberto Sassu +# +# Check if the kernel and evmctl provide the same result for HMAC calculation. + +trap '_report_exit_and_cleanup _cleanup_env cleanup' SIGINT SIGTERM SIGSEGV EXIT + +# Base VERBOSE on the environment variable, if set. +VERBOSE="${VERBOSE:-0}" +TST_EVM_CHANGE_MODE="${TST_EVM_CHANGE_MODE:-0}" +IMA_UUID="28b23254-9467-44c0-b6ba-34b12e85a26f" + +PATCHES=( +'KEYS: encrypted: fix key instantiation with user-provided data' +'KEYS: encrypted: Instantiate key with user-provided decrypted data' +'smack: Set the SMACK64TRANSMUTE xattr in smack_inode_init_security()' +) + +# From security/integrity/evm/evm.h in kernel source directory +(( EVM_INIT_HMAC=0x0001 )) + +cd "$(dirname "$0")" || exit 1 +export PATH=$PWD/../src:$PATH +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH +. ./functions.sh +_require evmctl + +cleanup() { + if [ "$g_loop_mounted" = "1" ]; then + popd > /dev/null || exit "$FAIL" + umount "$g_mountpoint" + fi + + if [ -n "$g_dev" ]; then + losetup -d "$g_dev" + fi + + if [ -n "$g_image" ]; then + rm -f "$g_image" + fi + + if [ -n "$g_mountpoint" ]; then + rm -Rf "$g_mountpoint" + fi +} + +get_xattr() { + local format="hex" + + if [ "$1" = "security.selinux" ]; then + format="text" + fi + + getfattr -n "$1" -e "$format" -d "$2" 2> /dev/null | awk -F "=" '$1 == "'"$1"'" {if ("'"$format"'" == "hex") v=substr($2, 3); else { split($2, temp, "\""); v=temp[2] }; print v}' +} + +# Compare HMAC calculated by the kernel with that calculated by evmctl. +compare_xattr() { + local algo=$1 + local path=$2 + local evm_xattr evm_xattr_evmctl true_digest + + evm_xattr="$(get_xattr security.evm "$path")" + true_digest=$("$algo"sum /bin/true | awk '{print $1}') + # evm_xattr has an extra byte at the beginning for the xattr type. + if [ "${#evm_xattr}" != $(( ${#true_digest} + 2 )) ]; then + echo "${RED}Unexpected size of security.evm for $path${NORM}" + return "$FAIL" + fi + + evm_xattr_evmctl="$(evmctl hmac --smack -v -n "$path" --uuid="$IMA_UUID" -a "$algo" --hmackey "$g_hmackey" 2>&1 | awk -F " " '$1 == "hmac:" {print $2}')" + if [ "$evm_xattr" != "02$evm_xattr_evmctl" ]; then + echo "${RED}$path security.evm mismatch between the kernel and evmctl${NORM}" + return "$FAIL" + fi + + return "$OK" +} + +# The purpose of this test is to verify if the kernel and evmctl produce the +# same HMAC. +check_evm_hmac() { + echo "Test: ${FUNCNAME[0]} (evm_hash: $1, evm_value: $g_evm_value, algo: $1, fs: $2, lsm: $3)" + + if ! grep -q "$3" < /sys/kernel/security/lsm; then + echo "${CYAN}$3 LSM not active${NORM}" + return "$SKIP" + fi + + if [ "$3" = "selinux" ] && [ -n "$TST_ENV" ]; then + if [ -z "$(command -v load_policy 2> /dev/null)" ]; then + echo "${CYAN}Cannot find load_policy${NORM}" + return "$SKIP" + fi + + if ! load_policy -i; then + echo "${RED}SELinux policy loading failed${NORM}" + return "$FAIL" + else + # Undo selinuxfs mount done by load_policy (sysfs cannot be mounted twice, procfs works but causes umount warning) + umount /sys/fs/selinux + fi + fi + + if ! touch test-file; then + echo "${RED}Cannot create test-file${NORM}" + return "$FAIL" + fi + + compare_xattr "$1" test-file + return $? +} + +cleanup_evm_hmac() { + rm -f test-file +} + +# The purpose of this test is to verify that SMACK64TRANSMUTE is successfully +# set on a newly created directory, and that the HMAC on that directory is valid. +check_evm_hmac_transmute() { + echo "Test: ${FUNCNAME[0]} (evm_hash: $1, evm_value: $g_evm_value, algo: $1, fs: $2, lsm: $3)" + + if ! grep -q "$3" < /sys/kernel/security/lsm; then + echo "${CYAN}$3 LSM not active${NORM}" + return "$SKIP" + fi + + if [ ! -f /sys/kernel/security/integrity/evm/evm_xattrs ] || + ! grep -q SMACK64TRANSMUTE < /sys/kernel/security/integrity/evm/evm_xattrs; then + echo "${CYAN}Set CONFIG_EVM_ADD_XATTRS=y and CONFIG_EVM_EXTRA_SMACK_XATTRS=y in the kernel configuration${NORM}" + exit "$SKIP" + fi + + # Add a Smack rule for transmuting of test-dir/test-dir2 + if ! echo "_ system rwxatl" > /sys/fs/smackfs/load2; then + echo "${RED}Cannot set Smack policy${NORM}" + return "$FAIL" + fi + + # Smack adds security.SMACK64=_. + if ! mkdir test-dir; then + echo "${RED}Cannot create test-dir${NORM}" + return "$FAIL" + fi + + # Change the directory label so that transmuting happens. + if ! setfattr -n security.SMACK64 -v system test-dir; then + echo "${RED}Cannot set security.SMACK64 on test-dir${NORM}" + return "$FAIL" + fi + + # Add the transmute xattr so that transmuting happens. + if ! setfattr -n security.SMACK64TRANSMUTE -v TRUE test-dir; then + echo "${RED}Cannot set security.SMACK64TRANSMUTE on test-dir${NORM}" + return "$FAIL" + fi + + compare_xattr "$1" test-dir + result=$? + + if [ "$result" -ne "$OK" ]; then + return "$result" + fi + + # Smack adds security.SMACK64=system and security.SMACK64TRANSMUTE=TRUE. + if ! mkdir test-dir/test-dir2; then + echo "${RED}Cannot create test-dir/test-dir2${NORM}" + return "$FAIL" + fi + + compare_xattr "$1" test-dir/test-dir2 + return $? +} + +cleanup_evm_hmac_transmute() { + rm -Rf test-dir +} + +if [ $$ -ne 1 ]; then + # Run in the new environment if TST_ENV is set. + + # SElinux enabled + _run_env "$TST_KERNEL" "$PWD/$(basename "$0")" "TST_ENV=$TST_ENV TST_KERNEL=$TST_KERNEL PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH VERBOSE=$VERBOSE TST_LIST=check_evm_hmac security=selinux enforcing=0" + + # Smack enabled + _run_env "$TST_KERNEL" "$PWD/$(basename "$0")" "TST_ENV=$TST_ENV TST_KERNEL=$TST_KERNEL PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH VERBOSE=$VERBOSE security=smack" + + # Exit from the creator of the new environment. + _exit_env "$TST_KERNEL" +fi + +# Mount filesystems in the new environment. +_init_env + +# Assume that the EVM mode can be changed in a new environment. +if [ -z "$TST_ENV" ] && [ "$TST_EVM_CHANGE_MODE" -eq 0 ]; then + echo "${CYAN}TST_EVM_CHANGE_MODE env variable must be set to 1${NORM}" + exit "$SKIP" +fi + +g_lsm_init_xattr=$(awk '$1 ~ /(smack|selinux)/' < /sys/kernel/security/lsm) +if [ -z "$g_lsm_init_xattr" ]; then + echo "${CYAN}Either Smack or SELinux must be active in the system for security.evm to be set${NORM}" + exit "$SKIP" +fi + +g_mountpoint="$(mktemp -d)" +g_image="$(mktemp)" + +if [ -z "$g_mountpoint" ]; then + echo "${RED}Mountpoint directory not created${NORM}" + exit "$FAIL" +fi + +if [ "$(whoami)" != "root" ]; then + echo "${CYAN}This script must be executed as root${NORM}" + exit "$SKIP" +fi + +if ! evmctl -h | grep -q hmackey; then + echo "${CYAN}Missing HMAC support, run: ./configure --enable-debug${NORM}" + exit "$SKIP" +fi + +if ! dd if=/dev/zero of="$g_image" bs=1M count=10 &> /dev/null; then + echo "${RED}Cannot create test image${NORM}" + exit "$FAIL" +fi + +g_dev="$(losetup -f "$g_image" --show)" +if [ -z "$g_dev" ]; then + echo "${RED}Cannot create loop device${NORM}" + exit "$FAIL" +fi + +if ! mkfs.ext4 -U $IMA_UUID -b 4096 "$g_dev" &> /dev/null; then + echo "${RED}Cannot format $g_dev${NORM}" + exit "$FAIL" +fi + +if ! mount "$g_dev" "$g_mountpoint"; then + echo "${RED}Cannot mount loop device${NORM}" + exit "$FAIL" +fi + +g_loop_mounted=1 +chmod 777 "$g_mountpoint" +pushd "$g_mountpoint" > /dev/null || exit "$FAIL" + +if [ -f /sys/kernel/security/evm ]; then + g_evm_value=$(cat /sys/kernel/security/evm) +fi + +g_hmackey_data="abcdefABCDEF1234567890aaaaaaaaaaabcdefABCDEF1234567890aaaaaaaaaa" + +g_hmackey="$(mktemp)" +echo $g_hmackey_data | xxd -r -p > "$g_hmackey" + +if [ -n "$g_evm_value" ] && [ $((g_evm_value & EVM_INIT_HMAC)) -ne $EVM_INIT_HMAC ]; then + g_evm_id="$(keyctl add encrypted evm-key "new enc32 user:kmk 32 $g_hmackey_data" @u)" + if ! echo "$EVM_INIT_HMAC" | tee /sys/kernel/security/evm &> /dev/null; then + # Retry with sudo -i, to force search in the root user keyring. + if ! echo "$EVM_INIT_HMAC" | sudo -i tee /sys/kernel/security/evm &> /dev/null; then + keyctl unlink "$g_evm_id" + echo "${RED}Failed to initialize EVM${NORM}" + exit "$FAIL" + fi + fi + + g_evm_value=$(cat /sys/kernel/security/evm) +fi + +expect_pass_if '0 1' check_evm_hmac sha1 ext4 selinux +cleanup_evm_hmac +expect_pass_if '0 1' check_evm_hmac sha1 ext4 smack +cleanup_evm_hmac + +expect_pass_if '2' check_evm_hmac_transmute sha1 ext4 smack +cleanup_evm_hmac_transmute diff --git a/tests/functions.sh b/tests/functions.sh index ed06040b394..35e925cc963 100755 --- a/tests/functions.sh +++ b/tests/functions.sh @@ -434,6 +434,9 @@ _init_env() { mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t securityfs securityfs /sys/kernel/security + if grep -q smack < /sys/kernel/security/lsm; then + mount -t smackfs smackfs /sys/fs/smackfs + fi if [ -n "$(command -v haveged 2> /dev/null)" ]; then $(command -v haveged) -w 1024 &> /dev/null @@ -455,6 +458,9 @@ _cleanup_env() { $1 + if grep -q smack < /sys/kernel/security/lsm; then + umount /sys/fs/smackfs + fi umount /sys/kernel/security umount /sys umount /proc