All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: linux-fscrypt@vger.kernel.org
Cc: Victor Hsieh <victorhsieh@google.com>
Subject: [fsverity-utils PATCH 2/4] programs/test_compute_digest: test the metadata callbacks
Date: Thu,  3 Jun 2021 12:58:10 -0700	[thread overview]
Message-ID: <20210603195812.50838-3-ebiggers@kernel.org> (raw)
In-Reply-To: <20210603195812.50838-1-ebiggers@kernel.org>

From: Eric Biggers <ebiggers@google.com>

Test that the libfsverity_metadata_callbacks support seems to be working
correctly.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 programs/test_compute_digest.c | 133 +++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/programs/test_compute_digest.c b/programs/test_compute_digest.c
index e7f2645..67266fa 100644
--- a/programs/test_compute_digest.c
+++ b/programs/test_compute_digest.c
@@ -13,6 +13,7 @@
 
 #include <ctype.h>
 #include <inttypes.h>
+#include <openssl/sha.h>
 
 struct mem_file {
 	u8 *data;
@@ -37,6 +38,13 @@ static int error_read_fn(void *fd __attribute__((unused)),
 	return -EIO;
 }
 
+static int zeroes_read_fn(void *fd __attribute__((unused)),
+			  void *buf, size_t count)
+{
+	memset(buf, 0, count);
+	return 0;
+}
+
 static const struct test_case {
 	u32 hash_algorithm;
 	u32 block_size;
@@ -249,6 +257,130 @@ static void test_invalid_params(void)
 	ASSERT(d == NULL);
 }
 
+static struct {
+	u64 merkle_tree_size;
+	u64 merkle_tree_block;
+	u64 descriptor;
+} metadata_callback_counts;
+
+static int handle_merkle_tree_size(void *ctx, u64 size)
+{
+	metadata_callback_counts.merkle_tree_size++;
+
+	/* Test that the ctx argument is passed through correctly. */
+	ASSERT(ctx == (void *)1);
+
+	/* Test that the expected Merkle tree size is reported. */
+	ASSERT(size == 5 * 1024);
+	return 0;
+}
+
+static int handle_merkle_tree_block(void *ctx, const void *block, size_t size,
+				    u64 offset)
+{
+	u8 digest[SHA256_DIGEST_LENGTH];
+	u64 count = metadata_callback_counts.merkle_tree_block++;
+	const char *expected_digest;
+
+	/* Test that ->merkle_tree_size() was called first. */
+	ASSERT(metadata_callback_counts.merkle_tree_size == 1);
+
+	/* Test that the ctx argument is passed through correctly. */
+	ASSERT(ctx == (void *)1);
+
+	/*
+	 * Test that this Merkle tree block has the expected size, offset, and
+	 * contents.  The 4 blocks at "level 0" should be reported first, in
+	 * order; then the 1 block at "level 1" should be reported last (but the
+	 * level 1 block should have the smallest offset).
+	 */
+	ASSERT(size == 1024);
+	SHA256(block, size, digest);
+	if (count == 4) {
+		/* 1 block at level 1 */
+		ASSERT(offset == 0);
+		expected_digest = "\x68\xc5\x38\xe1\x19\x58\xd6\x5d"
+				  "\x68\xb6\xfe\x8e\x9f\xb8\xcc\xab"
+				  "\xec\xfd\x92\x8b\x01\xd0\x63\x44"
+				  "\xe2\x23\xed\x41\xdd\xc4\x54\x4a";
+	} else {
+		/* 4 blocks at level 0 */
+		ASSERT(offset == 1024 + (count * 1024));
+		if (count < 3) {
+			expected_digest = "\xf7\x89\xba\xab\x53\x85\x9f\xaf"
+					  "\x36\xd6\xd7\x5d\x10\x42\x06\x42"
+					  "\x94\x20\x2d\x6e\x13\xe7\x71\x6f"
+					  "\x39\x4f\xba\x43\x4c\xcc\x49\x86";
+		} else {
+			expected_digest = "\x00\xfe\xd0\x3c\x5d\x6e\xab\x21"
+					  "\x31\x43\xf3\xd9\x6a\x5c\xa3\x1c"
+					  "\x2b\x89\xf5\x68\x4e\x6c\x8e\x07"
+					  "\x87\x3e\x5e\x97\x65\x17\xb4\x8f";
+		}
+	}
+	ASSERT(!memcmp(digest, expected_digest, SHA256_DIGEST_LENGTH));
+	return 0;
+}
+
+static const u8 expected_file_digest[SHA256_DIGEST_LENGTH] =
+	"\x09\xcb\xba\xee\xd2\xa0\x4c\x2d\xa2\x42\xc1\x0e\x15\x68\xd9\x6f"
+	"\x35\x8a\x16\xaa\x1e\xbe\x8c\xf0\x28\x61\x20\xc1\x3c\x93\x66\xd1";
+
+static int handle_descriptor(void *ctx, const void *descriptor, size_t size)
+{
+	u8 digest[SHA256_DIGEST_LENGTH];
+
+	metadata_callback_counts.descriptor++;
+	/* Test that the ctx argument is passed through correctly. */
+	ASSERT(ctx == (void *)1);
+
+	/* Test that the fs-verity descriptor is reported correctly. */
+	ASSERT(size == 256);
+	SHA256(descriptor, size, digest);
+	ASSERT(!memcmp(digest, expected_file_digest, SHA256_DIGEST_LENGTH));
+	return 0;
+}
+
+static const struct libfsverity_metadata_callbacks metadata_callbacks = {
+	.ctx = (void *)1, /* arbitrary value for testing purposes */
+	.merkle_tree_size = handle_merkle_tree_size,
+	.merkle_tree_block = handle_merkle_tree_block,
+	.descriptor = handle_descriptor,
+};
+
+/* Test that the libfsverity_metadata_callbacks work correctly. */
+static void test_metadata_callbacks(void)
+{
+	/*
+	 * For a useful test, we want a file whose Merkle tree will have at
+	 * least 2 levels (this one will have exactly 2).  The contents of the
+	 * file aren't too important.
+	 */
+	struct libfsverity_merkle_tree_params params = {
+		.version = 1,
+		.hash_algorithm = FS_VERITY_HASH_ALG_SHA256,
+		.block_size = 1024,
+		.file_size = 100000,
+		.metadata_callbacks = &metadata_callbacks,
+	};
+	struct libfsverity_digest *d;
+
+	ASSERT(libfsverity_compute_digest(NULL, zeroes_read_fn,
+					  &params, &d) == 0);
+
+	/* Test that the callbacks were called the correct number of times. */
+	ASSERT(metadata_callback_counts.merkle_tree_size == 1);
+	ASSERT(metadata_callback_counts.merkle_tree_block == 5);
+	ASSERT(metadata_callback_counts.descriptor == 1);
+
+	/* Test that the computed file digest is as expected. */
+	ASSERT(d->digest_algorithm == FS_VERITY_HASH_ALG_SHA256);
+	ASSERT(d->digest_size == SHA256_DIGEST_LENGTH);
+	ASSERT(!memcmp(d->digest, expected_file_digest, SHA256_DIGEST_LENGTH));
+
+	free(d);
+}
+
 int main(int argc, char *argv[])
 {
 	const bool update = (argc == 2 && !strcmp(argv[1], "--update"));
@@ -305,6 +437,7 @@ int main(int argc, char *argv[])
 	}
 
 	test_invalid_params();
+	test_metadata_callbacks();
 	printf("test_compute_digest passed\n");
 	return 0;
 }
-- 
2.31.1


  parent reply	other threads:[~2021-06-03 20:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-03 19:58 [fsverity-utils PATCH 0/4] Add option to write Merkle tree to a file Eric Biggers
2021-06-03 19:58 ` [fsverity-utils PATCH 1/4] lib/compute_digest: add callbacks for getting the verity metadata Eric Biggers
2021-06-03 19:58 ` Eric Biggers [this message]
2021-06-03 19:58 ` [fsverity-utils PATCH 3/4] programs/utils: add full_pwrite() and preallocate_file() Eric Biggers
2021-06-04  0:33   ` Victor Hsieh
2021-06-04  0:57     ` Eric Biggers
2021-06-04 15:24       ` Victor Hsieh
2021-06-04 16:55         ` Eric Biggers
2021-06-03 19:58 ` [fsverity-utils PATCH 4/4] programs/fsverity: add --out-merkle-tree and --out-descriptor options Eric Biggers
2021-06-04 15:25 ` [fsverity-utils PATCH 0/4] Add option to write Merkle tree to a file Victor Hsieh
2021-06-09  6:48 ` 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=20210603195812.50838-3-ebiggers@kernel.org \
    --to=ebiggers@kernel.org \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=victorhsieh@google.com \
    /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.