fsverity: replace fsverity_hash_page() with fsverity_hash_block()
authorEric Biggers <ebiggers@google.com>
Fri, 23 Dec 2022 20:36:32 +0000 (12:36 -0800)
committerEric Biggers <ebiggers@google.com>
Tue, 10 Jan 2023 03:06:01 +0000 (19:06 -0800)
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: Eric Biggers <ebiggers@google.com>
Reviewed-by: Andrey Albershteyn <aalbersh@redhat.com>
Tested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Link: https://lore.kernel.org/r/20221223203638.41293-6-ebiggers@kernel.org
fs/verity/enable.c
fs/verity/fsverity_private.h
fs/verity/hash_algs.c
fs/verity/verify.c

index 8a9189d4798375c819d59f1d7417baae174f5950..144483319f1a33fe84914209971d39916f4bc92c 100644 (file)
@@ -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,
-                                        &pending_hashes[pending_size]);
+               err = fsverity_hash_block(params, inode, req, src_page, 0,
+                                         &pending_hashes[pending_size]);
                put_page(src_page);
                if (err)
                        return err;
index fc1c2797fab19c5dc21c65d8b156600c0237a8ac..23ded939d649fae994efbdac6e287b4db203e432 100644 (file)
@@ -88,9 +88,9 @@ void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
                                struct ahash_request *req);
 const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
                                      const u8 *salt, size_t salt_size);
-int fsverity_hash_page(const struct merkle_tree_params *params,
-                      const struct inode *inode,
-                      struct ahash_request *req, struct page *page, u8 *out);
+int fsverity_hash_block(const struct merkle_tree_params *params,
+                       const struct inode *inode, struct ahash_request *req,
+                       struct page *page, unsigned int offset, u8 *out);
 int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
                         const void *data, size_t size, u8 *out);
 void __init fsverity_check_hash_algs(void);
index 6f8170cf4ae71af71bec2303c12448f1481b528f..13fcf31be8441fbf5eb2e49511fc743df8174189 100644 (file)
@@ -220,35 +220,33 @@ err_free:
 }
 
 /**
- * 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
  * @inode: inode for which the hashing is being done
  * @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
  *
- * Hash a single data or hash block, assuming block_size == PAGE_SIZE.
- * The hash is salted if a salt is specified in the Merkle tree parameters.
+ * Hash a single data or hash block.  The hash is salted if a salt is specified
+ * in the Merkle tree parameters.
  *
  * Return: 0 on success, -errno on failure
  */
-int fsverity_hash_page(const struct merkle_tree_params *params,
-                      const struct inode *inode,
-                      struct ahash_request *req, struct page *page, u8 *out)
+int fsverity_hash_block(const struct merkle_tree_params *params,
+                       const struct inode *inode, struct ahash_request *req,
+                       struct page *page, unsigned int offset, u8 *out)
 {
        struct scatterlist sg;
        DECLARE_CRYPTO_WAIT(wait);
        int err;
 
-       if (WARN_ON(params->block_size != PAGE_SIZE))
-               return -EINVAL;
-
        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 |
                                        CRYPTO_TFM_REQ_MAY_BACKLOG,
                                   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) {
                err = crypto_ahash_import(req, params->hashstate);
@@ -264,7 +262,7 @@ int fsverity_hash_page(const struct merkle_tree_params *params,
 
        err = crypto_wait_req(err, &wait);
        if (err)
-               fsverity_err(inode, "Error %d computing page hash", err);
+               fsverity_err(inode, "Error %d computing block hash", err);
        return err;
 }
 
index d2fcb6a21ea8e50cad5b7c6e9328d1c6a6c81b27..44df06ddcc603d739e7b826f892f6fffe771e0b6 100644 (file)
@@ -125,12 +125,13 @@ static bool verify_page(struct inode *inode, const struct fsverity_info *vi,
 
        want_hash = vi->root_hash;
 descend:
-       /* Descend the tree verifying hash pages */
+       /* Descend the tree verifying hash blocks. */
        for (; level > 0; level--) {
                struct page *hpage = hpages[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)
                        goto out;
                err = cmp_hashes(vi, want_hash, real_hash, index, level - 1);
@@ -142,8 +143,8 @@ descend:
                put_page(hpage);
        }
 
-       /* Finally, verify the data page */
-       err = fsverity_hash_page(params, inode, req, data_page, real_hash);
+       /* Finally, verify the data block. */
+       err = fsverity_hash_block(params, inode, req, data_page, 0, real_hash);
        if (err)
                goto out;
        err = cmp_hashes(vi, want_hash, real_hash, index, -1);