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 \
    --subject='Re: [fsverity-utils PATCH 2/4] programs/test_compute_digest: test the metadata callbacks' \
    /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

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.