All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mimi Zohar <zohar@linux.ibm.com>
To: linux-integrity@vger.kernel.org
Cc: Mimi Zohar <zohar@linux.ibm.com>,
	Eric Biggers <ebiggers@kernel.org>,
	linux-fscrypt@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1 4/5] ima: support fs-verity file digest based signatures
Date: Thu,  2 Dec 2021 16:55:06 -0500	[thread overview]
Message-ID: <20211202215507.298415-5-zohar@linux.ibm.com> (raw)
In-Reply-To: <20211202215507.298415-1-zohar@linux.ibm.com>

Instead of calculating a file hash and verifying the signature stored
in the security.ima xattr against the calculated file hash, verify the
signature based on the fs-verity's file digest and other metadata.  The
fs-verity file digest is a hash that includes the Merkle tree root hash.

Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
---
Changelog v1:
- Based on Eric Bigger's review, instead of verifying the fsverity's file
digest directly, sign a hash of it with other file metadata.

 security/integrity/ima/ima_api.c      | 20 ++++++++++++
 security/integrity/ima/ima_appraise.c | 45 ++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 7505563315cb..4fe7bc99378a 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -14,6 +14,7 @@
 #include <linux/xattr.h>
 #include <linux/evm.h>
 #include <linux/iversion.h>
+#include <linux/fsverity.h>
 
 #include "ima.h"
 
@@ -200,6 +201,23 @@ int ima_get_action(struct user_namespace *mnt_userns, struct inode *inode,
 				allowed_algos);
 }
 
+static int ima_collect_verity_digest(struct integrity_iint_cache *iint,
+				     struct ima_digest_data *hash)
+{
+	u8 verity_digest[FS_VERITY_MAX_DIGEST_SIZE];
+	enum hash_algo verity_alg;
+	int rc;
+
+	rc = fsverity_collect_digest(iint->inode, verity_digest, &verity_alg);
+	if (rc)
+		return -EINVAL;
+	if (hash->algo != verity_alg)
+		return -EINVAL;
+	hash->length = hash_digest_size[verity_alg];
+	memcpy(hash->digest, verity_digest, hash->length);
+	return 0;
+}
+
 /*
  * ima_collect_measurement - collect file measurement
  *
@@ -251,6 +269,8 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
 
 	if (buf)
 		result = ima_calc_buffer_hash(buf, size, &hash.hdr);
+	else if (veritysig)
+		result = ima_collect_verity_digest(iint, &hash.hdr);
 	else
 		result = ima_calc_file_hash(file, &hash.hdr);
 
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 549fe051269a..53938aa0497a 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -240,6 +240,11 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 			struct evm_ima_xattr_data *xattr_value, int xattr_len,
 			enum integrity_status *status, const char **cause)
 {
+	u8 verity_digest[IMA_MAX_DIGEST_SIZE + 1];
+	struct {
+		struct ima_digest_data hdr;
+		char digest[IMA_MAX_DIGEST_SIZE];
+	} hash;
 	int rc = -EINVAL, hash_start = 0;
 
 	switch (xattr_value->type) {
@@ -277,7 +282,45 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,
 		*status = INTEGRITY_PASS;
 		break;
 	case IMA_VERITY_DIGSIG:
-		fallthrough;
+		set_bit(IMA_DIGSIG, &iint->atomic_flags);
+
+		/*
+		 * The IMA signature is based on a hash of IMA_VERITY_DIGSIG
+		 * and the fs-verity file digest, not directly on the
+		 * fs-verity file digest.  Both digests should probably be
+		 * included in the IMA measurement list, but for now this
+		 * digest is only used for verifying the IMA signature.
+		 */
+		verity_digest[0] = IMA_VERITY_DIGSIG;
+		memcpy(verity_digest + 1, iint->ima_hash->digest,
+		       iint->ima_hash->length);
+
+		hash.hdr.algo = iint->ima_hash->algo;
+		hash.hdr.length = iint->ima_hash->length;
+
+		rc = ima_calc_buffer_hash(verity_digest,
+					  iint->ima_hash->length + 1,
+					  &hash.hdr);
+		if (rc) {
+			*cause = "verity-hashing-error";
+			*status = INTEGRITY_FAIL;
+			break;
+		}
+
+		rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
+					     (const char *)xattr_value,
+					      xattr_len,
+					      hash.hdr.digest,
+					      hash.hdr.length);
+
+		if (rc) {
+			*cause = "invalid-verity-signature";
+			*status = INTEGRITY_FAIL;
+		} else {
+			*status = INTEGRITY_PASS;
+		}
+
+		break;
 	case EVM_IMA_XATTR_DIGSIG:
 		set_bit(IMA_DIGSIG, &iint->atomic_flags);
 		rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
-- 
2.27.0


  parent reply	other threads:[~2021-12-02 21:55 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-02 21:55 [PATCH v1 0/5] ima: support fs-verity signatures stored as Mimi Zohar
2021-12-02 21:55 ` [PATCH v1 1/5] fs-verity: define a function to return the integrity protected file digest Mimi Zohar
2021-12-02 22:15   ` Eric Biggers
2021-12-02 21:55 ` [PATCH v1 2/5] ima: define a new signature type named IMA_VERITY_DIGSIG Mimi Zohar
2021-12-02 21:55 ` [PATCH v1 3/5] ima: limit including fs-verity's file digest in measurement list Mimi Zohar
2021-12-02 22:22   ` Eric Biggers
2021-12-02 22:55     ` Mimi Zohar
2021-12-02 21:55 ` Mimi Zohar [this message]
2021-12-02 22:07   ` [PATCH v1 4/5] ima: support fs-verity file digest based signatures Eric Biggers
2021-12-02 22:13     ` Mimi Zohar
2021-12-02 22:18       ` Eric Biggers
2021-12-31 15:35     ` Mimi Zohar
2022-01-05 23:37       ` Eric Biggers
2022-01-09 20:45         ` Vitaly Chikunov
2022-01-09 21:07           ` Eric Biggers
2022-01-15  5:31             ` Vitaly Chikunov
2022-01-15  6:21               ` Eric Biggers
2022-01-16  3:31                 ` Stefan Berger
2022-01-16  5:24                   ` Stefan Berger
2022-01-19  0:49                   ` Eric Biggers
2022-01-19 15:41                     ` Stefan Berger
2022-01-16 17:01                 ` Mimi Zohar
2022-01-19  0:39                   ` Eric Biggers
2022-01-20 16:39                     ` Mimi Zohar
2022-01-20 21:05                       ` Eric Biggers
2021-12-02 21:55 ` [PATCH v1 5/5] fsverity: update the documentation Mimi Zohar
2021-12-02 22:09   ` Eric Biggers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211202215507.298415-5-zohar@linux.ibm.com \
    --to=zohar@linux.ibm.com \
    --cc=ebiggers@kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.