forked from alk3p/WSA-Linux-Kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fs-verity: add Kconfig and the helper functions for hashing
Add the beginnings of the fs/verity/ support layer, including the Kconfig option and various helper functions for hashing. To start, only SHA-256 is supported, but other hash algorithms can easily be added. Reviewed-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Jaegeuk Kim <jaegeuk@kernel.org> Signed-off-by: Eric Biggers <ebiggers@google.com>
- Loading branch information
Showing
7 changed files
with
449 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
config FS_VERITY | ||
bool "FS Verity (read-only file-based authenticity protection)" | ||
select CRYPTO | ||
# SHA-256 is selected as it's intended to be the default hash algorithm. | ||
# To avoid bloat, other wanted algorithms must be selected explicitly. | ||
select CRYPTO_SHA256 | ||
help | ||
This option enables fs-verity. fs-verity is the dm-verity | ||
mechanism implemented at the file level. On supported | ||
filesystems (currently EXT4 and F2FS), userspace can use an | ||
ioctl to enable verity for a file, which causes the filesystem | ||
to build a Merkle tree for the file. The filesystem will then | ||
transparently verify any data read from the file against the | ||
Merkle tree. The file is also made read-only. | ||
|
||
This serves as an integrity check, but the availability of the | ||
Merkle tree root hash also allows efficiently supporting | ||
various use cases where normally the whole file would need to | ||
be hashed at once, such as: (a) auditing (logging the file's | ||
hash), or (b) authenticity verification (comparing the hash | ||
against a known good value, e.g. from a digital signature). | ||
|
||
fs-verity is especially useful on large files where not all | ||
the contents may actually be needed. Also, fs-verity verifies | ||
data each time it is paged back in, which provides better | ||
protection against malicious disks vs. an ahead-of-time hash. | ||
|
||
If unsure, say N. | ||
|
||
config FS_VERITY_DEBUG | ||
bool "FS Verity debugging" | ||
depends on FS_VERITY | ||
help | ||
Enable debugging messages related to fs-verity by default. | ||
|
||
Say N unless you are an fs-verity developer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
obj-$(CONFIG_FS_VERITY) += hash_algs.o \ | ||
init.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* fs-verity: read-only file-based authenticity protection | ||
* | ||
* Copyright 2019 Google LLC | ||
*/ | ||
|
||
#ifndef _FSVERITY_PRIVATE_H | ||
#define _FSVERITY_PRIVATE_H | ||
|
||
#ifdef CONFIG_FS_VERITY_DEBUG | ||
#define DEBUG | ||
#endif | ||
|
||
#define pr_fmt(fmt) "fs-verity: " fmt | ||
|
||
#include <crypto/sha.h> | ||
#include <linux/fs.h> | ||
#include <uapi/linux/fsverity.h> | ||
|
||
struct ahash_request; | ||
|
||
/* | ||
* Implementation limit: maximum depth of the Merkle tree. For now 8 is plenty; | ||
* it's enough for over U64_MAX bytes of data using SHA-256 and 4K blocks. | ||
*/ | ||
#define FS_VERITY_MAX_LEVELS 8 | ||
|
||
/* | ||
* Largest digest size among all hash algorithms supported by fs-verity. | ||
* Currently assumed to be <= size of fsverity_descriptor::root_hash. | ||
*/ | ||
#define FS_VERITY_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE | ||
|
||
/* A hash algorithm supported by fs-verity */ | ||
struct fsverity_hash_alg { | ||
struct crypto_ahash *tfm; /* hash tfm, allocated on demand */ | ||
const char *name; /* crypto API name, e.g. sha256 */ | ||
unsigned int digest_size; /* digest size in bytes, e.g. 32 for SHA-256 */ | ||
unsigned int block_size; /* block size in bytes, e.g. 64 for SHA-256 */ | ||
}; | ||
|
||
/* Merkle tree parameters: hash algorithm, initial hash state, and topology */ | ||
struct merkle_tree_params { | ||
const struct fsverity_hash_alg *hash_alg; /* the hash algorithm */ | ||
const u8 *hashstate; /* initial hash state or NULL */ | ||
unsigned int digest_size; /* same as hash_alg->digest_size */ | ||
unsigned int block_size; /* size of data and tree blocks */ | ||
unsigned int hashes_per_block; /* number of hashes per tree block */ | ||
unsigned int log_blocksize; /* log2(block_size) */ | ||
unsigned int log_arity; /* log2(hashes_per_block) */ | ||
unsigned int num_levels; /* number of levels in Merkle tree */ | ||
u64 tree_size; /* Merkle tree size in bytes */ | ||
|
||
/* | ||
* Starting block index for each tree level, ordered from leaf level (0) | ||
* to root level ('num_levels - 1') | ||
*/ | ||
u64 level_start[FS_VERITY_MAX_LEVELS]; | ||
}; | ||
|
||
/* hash_algs.c */ | ||
|
||
extern struct fsverity_hash_alg fsverity_hash_algs[]; | ||
|
||
const struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode, | ||
unsigned int num); | ||
const u8 *fsverity_prepare_hash_state(const 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_buffer(const struct fsverity_hash_alg *alg, | ||
const void *data, size_t size, u8 *out); | ||
void __init fsverity_check_hash_algs(void); | ||
|
||
/* init.c */ | ||
|
||
extern void __printf(3, 4) __cold | ||
fsverity_msg(const struct inode *inode, const char *level, | ||
const char *fmt, ...); | ||
|
||
#define fsverity_warn(inode, fmt, ...) \ | ||
fsverity_msg((inode), KERN_WARNING, fmt, ##__VA_ARGS__) | ||
#define fsverity_err(inode, fmt, ...) \ | ||
fsverity_msg((inode), KERN_ERR, fmt, ##__VA_ARGS__) | ||
|
||
#endif /* _FSVERITY_PRIVATE_H */ |
Oops, something went wrong.