Commit f45555bf authored by Eric Biggers's avatar Eric Biggers

fsverity: replace fsverity_hash_page() with fsverity_hash_block()

In preparation for allowing the Merkle tree block size to differ from
PAGE_SIZE, replace fsverity_hash_page() with fsverity_hash_block().  The
new function is similar to the old one, but it operates on the block at
the given offset in the page instead of on the full page.

(For now, all callers still pass a full page.)
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Reviewed-by: default avatarAndrey Albershteyn <aalbersh@redhat.com>
Tested-by: default avatarOjaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://lore.kernel.org/r/20221223203638.41293-6-ebiggers@kernel.org
parent 55eed69c
...@@ -99,8 +99,8 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level, ...@@ -99,8 +99,8 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level,
} }
} }
err = fsverity_hash_page(params, inode, req, src_page, err = fsverity_hash_block(params, inode, req, src_page, 0,
&pending_hashes[pending_size]); &pending_hashes[pending_size]);
put_page(src_page); put_page(src_page);
if (err) if (err)
return err; return err;
......
...@@ -88,9 +88,9 @@ void fsverity_free_hash_request(struct fsverity_hash_alg *alg, ...@@ -88,9 +88,9 @@ void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
struct ahash_request *req); struct ahash_request *req);
const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg, const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
const u8 *salt, size_t salt_size); const u8 *salt, size_t salt_size);
int fsverity_hash_page(const struct merkle_tree_params *params, int fsverity_hash_block(const struct merkle_tree_params *params,
const struct inode *inode, const struct inode *inode, struct ahash_request *req,
struct ahash_request *req, struct page *page, u8 *out); struct page *page, unsigned int offset, u8 *out);
int fsverity_hash_buffer(struct fsverity_hash_alg *alg, int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
const void *data, size_t size, u8 *out); const void *data, size_t size, u8 *out);
void __init fsverity_check_hash_algs(void); void __init fsverity_check_hash_algs(void);
......
...@@ -220,35 +220,33 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg, ...@@ -220,35 +220,33 @@ const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
} }
/** /**
* fsverity_hash_page() - hash a single data or hash page * fsverity_hash_block() - hash a single data or hash block
* @params: the Merkle tree's parameters * @params: the Merkle tree's parameters
* @inode: inode for which the hashing is being done * @inode: inode for which the hashing is being done
* @req: preallocated hash request * @req: preallocated hash request
* @page: the page to hash * @page: the page containing the block to hash
* @offset: the offset of the block within @page
* @out: output digest, size 'params->digest_size' bytes * @out: output digest, size 'params->digest_size' bytes
* *
* Hash a single data or hash block, assuming block_size == PAGE_SIZE. * Hash a single data or hash block. The hash is salted if a salt is specified
* The hash is salted if a salt is specified in the Merkle tree parameters. * in the Merkle tree parameters.
* *
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
int fsverity_hash_page(const struct merkle_tree_params *params, int fsverity_hash_block(const struct merkle_tree_params *params,
const struct inode *inode, const struct inode *inode, struct ahash_request *req,
struct ahash_request *req, struct page *page, u8 *out) struct page *page, unsigned int offset, u8 *out)
{ {
struct scatterlist sg; struct scatterlist sg;
DECLARE_CRYPTO_WAIT(wait); DECLARE_CRYPTO_WAIT(wait);
int err; int err;
if (WARN_ON(params->block_size != PAGE_SIZE))
return -EINVAL;
sg_init_table(&sg, 1); sg_init_table(&sg, 1);
sg_set_page(&sg, page, PAGE_SIZE, 0); sg_set_page(&sg, page, params->block_size, offset);
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
CRYPTO_TFM_REQ_MAY_BACKLOG, CRYPTO_TFM_REQ_MAY_BACKLOG,
crypto_req_done, &wait); crypto_req_done, &wait);
ahash_request_set_crypt(req, &sg, out, PAGE_SIZE); ahash_request_set_crypt(req, &sg, out, params->block_size);
if (params->hashstate) { if (params->hashstate) {
err = crypto_ahash_import(req, params->hashstate); err = crypto_ahash_import(req, params->hashstate);
...@@ -264,7 +262,7 @@ int fsverity_hash_page(const struct merkle_tree_params *params, ...@@ -264,7 +262,7 @@ int fsverity_hash_page(const struct merkle_tree_params *params,
err = crypto_wait_req(err, &wait); err = crypto_wait_req(err, &wait);
if (err) if (err)
fsverity_err(inode, "Error %d computing page hash", err); fsverity_err(inode, "Error %d computing block hash", err);
return err; return err;
} }
......
...@@ -125,12 +125,13 @@ static bool verify_page(struct inode *inode, const struct fsverity_info *vi, ...@@ -125,12 +125,13 @@ static bool verify_page(struct inode *inode, const struct fsverity_info *vi,
want_hash = vi->root_hash; want_hash = vi->root_hash;
descend: descend:
/* Descend the tree verifying hash pages */ /* Descend the tree verifying hash blocks. */
for (; level > 0; level--) { for (; level > 0; level--) {
struct page *hpage = hpages[level - 1]; struct page *hpage = hpages[level - 1];
unsigned int hoffset = hoffsets[level - 1]; unsigned int hoffset = hoffsets[level - 1];
err = fsverity_hash_page(params, inode, req, hpage, real_hash); err = fsverity_hash_block(params, inode, req, hpage, 0,
real_hash);
if (err) if (err)
goto out; goto out;
err = cmp_hashes(vi, want_hash, real_hash, index, level - 1); err = cmp_hashes(vi, want_hash, real_hash, index, level - 1);
...@@ -142,8 +143,8 @@ static bool verify_page(struct inode *inode, const struct fsverity_info *vi, ...@@ -142,8 +143,8 @@ static bool verify_page(struct inode *inode, const struct fsverity_info *vi,
put_page(hpage); put_page(hpage);
} }
/* Finally, verify the data page */ /* Finally, verify the data block. */
err = fsverity_hash_page(params, inode, req, data_page, real_hash); err = fsverity_hash_block(params, inode, req, data_page, 0, real_hash);
if (err) if (err)
goto out; goto out;
err = cmp_hashes(vi, want_hash, real_hash, index, -1); err = cmp_hashes(vi, want_hash, real_hash, index, -1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment