@@ -52,6 +52,8 @@ static int write_merkle_tree_block(struct inode *inode, const u8 *buf,
{
struct fsverity_writemerkle req = {
.inode = inode,
+ .zero_digest = params->zero_digest,
+ .digest_size = params->digest_size,
};
u64 pos = (u64)index << params->log_blocksize;
int err;
@@ -47,6 +47,9 @@ struct merkle_tree_params {
u64 tree_size; /* Merkle tree size in bytes */
unsigned long tree_pages; /* Merkle tree size in pages */
+ /* the hash of a merkle block-sized buffer of zeroes */
+ u8 zero_digest[FS_VERITY_MAX_DIGEST_SIZE];
+
/*
* Starting block index for each tree level, ordered from leaf level (0)
* to root level ('num_levels - 1')
@@ -144,6 +144,13 @@ int fsverity_init_merkle_tree_params(struct merkle_tree_params *params,
goto out_err;
}
+ err = fsverity_hash_block(params, inode, page_address(ZERO_PAGE(0)),
+ params->zero_digest);
+ if (err) {
+ fsverity_err(inode, "Error %d computing zero digest", err);
+ goto out_err;
+ }
+
params->tree_size = offset << log_blocksize;
params->tree_pages = PAGE_ALIGN(params->tree_size) >> PAGE_SHIFT;
return 0;
@@ -425,6 +425,8 @@ int fsverity_read_merkle_tree_block(struct inode *inode,
.level = level,
.num_levels = params->num_levels,
.ra_bytes = ra_bytes,
+ .zero_digest = params->zero_digest,
+ .digest_size = params->digest_size,
};
err = vops->read_merkle_tree_block(&req, block);
@@ -63,12 +63,16 @@ struct fsverity_blockbuf {
* if the page at @block->offset isn't already cached.
* Implementations may ignore this argument; it's only a
* performance optimization.
+ * @zero_digest: the hash of a merkle block-sized buffer of zeroes
+ * @digest_size: size of zero_digest, in bytes
*/
struct fsverity_readmerkle {
struct inode *inode;
unsigned long ra_bytes;
int level;
int num_levels;
+ const u8 *zero_digest;
+ unsigned int digest_size;
};
#define FSVERITY_STREAMING_READ (-1)
@@ -76,9 +80,13 @@ struct fsverity_readmerkle {
/**
* struct fsverity_writemerkle - Request to write a Merkle Tree block buffer
* @inode: the inode to read
+ * @zero_digest: the hash of a merkle block-sized buffer of zeroes
+ * @digest_size: size of zero_digest, in bytes
*/
struct fsverity_writemerkle {
struct inode *inode;
+ const u8 *zero_digest;
+ unsigned int digest_size;
};
/* Verity operations for filesystems */