671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 1) /* SPDX-License-Identifier: GPL-2.0 */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 2) /*
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 3) * fs-verity: read-only file-based authenticity protection
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 4) *
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 5) * Copyright 2019 Google LLC
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 6) */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 7)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 8) #ifndef _FSVERITY_PRIVATE_H
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 9) #define _FSVERITY_PRIVATE_H
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 10)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 11) #ifdef CONFIG_FS_VERITY_DEBUG
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 12) #define DEBUG
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 13) #endif
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 14)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 15) #define pr_fmt(fmt) "fs-verity: " fmt
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 16)
a24d22b225ce1 (Eric Biggers 2020-11-12 21:20:21 -0800 17) #include <crypto/sha2.h>
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 18) #include <linux/fsverity.h>
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 19) #include <linux/mempool.h>
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 20)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 21) struct ahash_request;
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 22)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 23) /*
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 24) * Implementation limit: maximum depth of the Merkle tree. For now 8 is plenty;
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 25) * it's enough for over U64_MAX bytes of data using SHA-256 and 4K blocks.
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 26) */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 27) #define FS_VERITY_MAX_LEVELS 8
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 28)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 29) /*
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 30) * Largest digest size among all hash algorithms supported by fs-verity.
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 31) * Currently assumed to be <= size of fsverity_descriptor::root_hash.
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 32) */
add890c9f9d2d (Eric Biggers 2019-07-22 09:26:23 -0700 33) #define FS_VERITY_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 34)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 35) /* A hash algorithm supported by fs-verity */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 36) struct fsverity_hash_alg {
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 37) struct crypto_ahash *tfm; /* hash tfm, allocated on demand */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 38) const char *name; /* crypto API name, e.g. sha256 */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 39) unsigned int digest_size; /* digest size in bytes, e.g. 32 for SHA-256 */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 40) unsigned int block_size; /* block size in bytes, e.g. 64 for SHA-256 */
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 41) mempool_t req_pool; /* mempool with a preallocated hash request */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 42) };
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 43)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 44) /* Merkle tree parameters: hash algorithm, initial hash state, and topology */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 45) struct merkle_tree_params {
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 46) struct fsverity_hash_alg *hash_alg; /* the hash algorithm */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 47) const u8 *hashstate; /* initial hash state or NULL */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 48) unsigned int digest_size; /* same as hash_alg->digest_size */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 49) unsigned int block_size; /* size of data and tree blocks */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 50) unsigned int hashes_per_block; /* number of hashes per tree block */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 51) unsigned int log_blocksize; /* log2(block_size) */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 52) unsigned int log_arity; /* log2(hashes_per_block) */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 53) unsigned int num_levels; /* number of levels in Merkle tree */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 54) u64 tree_size; /* Merkle tree size in bytes */
fd39073dba863 (Eric Biggers 2020-01-06 12:55:33 -0800 55) unsigned long level0_blocks; /* number of blocks in tree level 0 */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 56)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 57) /*
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 58) * Starting block index for each tree level, ordered from leaf level (0)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 59) * to root level ('num_levels - 1')
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 60) */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 61) u64 level_start[FS_VERITY_MAX_LEVELS];
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 62) };
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 63)
6377a38bd345b (Eric Biggers 2020-05-11 12:21:17 -0700 64) /*
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 65) * fsverity_info - cached verity metadata for an inode
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 66) *
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 67) * When a verity file is first opened, an instance of this struct is allocated
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 68) * and stored in ->i_verity_info; it remains until the inode is evicted. It
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 69) * caches information about the Merkle tree that's needed to efficiently verify
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800 70) * data read from the file. It also caches the file digest. The Merkle tree
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800 71) * pages themselves are not cached here, but the filesystem may cache them.
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 72) */
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 73) struct fsverity_info {
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 74) struct merkle_tree_params tree_params;
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 75) u8 root_hash[FS_VERITY_MAX_DIGEST_SIZE];
ed45e20164934 (Eric Biggers 2020-11-13 13:19:17 -0800 76) u8 file_digest[FS_VERITY_MAX_DIGEST_SIZE];
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 77) const struct inode *inode;
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 78) };
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 79)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 80) /* Arbitrary limit to bound the kmalloc() size. Can be changed. */
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 81) #define FS_VERITY_MAX_DESCRIPTOR_SIZE 16384
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 82)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 83) #define FS_VERITY_MAX_SIGNATURE_SIZE (FS_VERITY_MAX_DESCRIPTOR_SIZE - \
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 84) sizeof(struct fsverity_descriptor))
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 85)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 86) /* hash_algs.c */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 87)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 88) extern struct fsverity_hash_alg fsverity_hash_algs[];
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 89)
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 90) struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 91) unsigned int num);
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 92) struct ahash_request *fsverity_alloc_hash_request(struct fsverity_hash_alg *alg,
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 93) gfp_t gfp_flags);
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 94) void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 95) struct ahash_request *req);
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 96) const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 97) const u8 *salt, size_t salt_size);
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 98) int fsverity_hash_page(const struct merkle_tree_params *params,
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 99) const struct inode *inode,
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 100) struct ahash_request *req, struct page *page, u8 *out);
439bea104c3d2 (Eric Biggers 2019-12-31 11:55:45 -0600 101) int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 102) const void *data, size_t size, u8 *out);
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 103) void __init fsverity_check_hash_algs(void);
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 104)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 105) /* init.c */
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 106)
9cd6b593cfc9e (Eric Biggers 2020-05-11 12:21:18 -0700 107) void __printf(3, 4) __cold
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 108) fsverity_msg(const struct inode *inode, const char *level,
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 109) const char *fmt, ...);
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 110)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 111) #define fsverity_warn(inode, fmt, ...) \
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 112) fsverity_msg((inode), KERN_WARNING, fmt, ##__VA_ARGS__)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 113) #define fsverity_err(inode, fmt, ...) \
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 114) fsverity_msg((inode), KERN_ERR, fmt, ##__VA_ARGS__)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 115)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 116) /* open.c */
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 117)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 118) int fsverity_init_merkle_tree_params(struct merkle_tree_params *params,
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 119) const struct inode *inode,
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 120) unsigned int hash_algorithm,
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 121) unsigned int log_blocksize,
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 122) const u8 *salt, size_t salt_size);
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 123)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 124) struct fsverity_info *fsverity_create_info(const struct inode *inode,
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 125) struct fsverity_descriptor *desc,
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 126) size_t desc_size);
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 127)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 128) void fsverity_set_info(struct inode *inode, struct fsverity_info *vi);
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 129)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 130) void fsverity_free_info(struct fsverity_info *vi);
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 131)
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 132) int fsverity_get_descriptor(struct inode *inode,
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 133) struct fsverity_descriptor **desc_ret,
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 134) size_t *desc_size_ret);
c2c8261151b32 (Eric Biggers 2021-01-15 10:18:14 -0800 135)
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 136) int __init fsverity_init_info_cache(void);
8a1d0f9cacc99 (Eric Biggers 2019-07-22 09:26:22 -0700 137) void __init fsverity_exit_info_cache(void);
8a1d0f9cacc99 (Eric Biggers 2019-07-22 09:26:22 -0700 138)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 139) /* signature.c */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 140)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 141) #ifdef CONFIG_FS_VERITY_BUILTIN_SIGNATURES
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 142) int fsverity_verify_signature(const struct fsverity_info *vi,
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800 143) const u8 *signature, size_t sig_size);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 144)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 145) int __init fsverity_init_signature(void);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 146) #else /* !CONFIG_FS_VERITY_BUILTIN_SIGNATURES */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 147) static inline int
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 148) fsverity_verify_signature(const struct fsverity_info *vi,
fab634c4de460 (Eric Biggers 2021-01-15 10:18:15 -0800 149) const u8 *signature, size_t sig_size)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 150) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 151) return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 152) }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 153)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 154) static inline int fsverity_init_signature(void)
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 155) {
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 156) return 0;
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 157) }
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 158) #endif /* !CONFIG_FS_VERITY_BUILTIN_SIGNATURES */
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 159)
8a1d0f9cacc99 (Eric Biggers 2019-07-22 09:26:22 -0700 160) /* verify.c */
8a1d0f9cacc99 (Eric Biggers 2019-07-22 09:26:22 -0700 161)
8a1d0f9cacc99 (Eric Biggers 2019-07-22 09:26:22 -0700 162) int __init fsverity_init_workqueue(void);
432434c9f8e18 (Eric Biggers 2019-07-22 09:26:23 -0700 163) void __init fsverity_exit_workqueue(void);
fd2d1acfcadfe (Eric Biggers 2019-07-22 09:26:22 -0700 164)
671e67b47e9ff (Eric Biggers 2019-07-22 09:26:21 -0700 165) #endif /* _FSVERITY_PRIVATE_H */