diff options
author | Eric Biggers <ebiggers@google.com> | 2019-07-22 18:26:23 +0200 |
---|---|---|
committer | Eric Biggers <ebiggers@google.com> | 2019-08-13 04:33:50 +0200 |
commit | 432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6 (patch) | |
tree | cfcf57b2bb1fbdb1e9b5739f020b0311405363c0 /fs/verity/open.c | |
parent | fs-verity: add SHA-512 support (diff) | |
download | linux-432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6.tar.xz linux-432434c9f8e18cb4cf0fe05bc3eeceada0e10dc6.zip |
fs-verity: support builtin file signatures
To meet some users' needs, add optional support for having fs-verity
handle a portion of the authentication policy in the kernel. An
".fs-verity" keyring is created to which X.509 certificates can be
added; then a sysctl 'fs.verity.require_signatures' can be set to cause
the kernel to enforce that all fs-verity files contain a signature of
their file measurement by a key in this keyring.
See the "Built-in signature verification" section of
Documentation/filesystems/fsverity.rst for the full documentation.
Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Eric Biggers <ebiggers@google.com>
Diffstat (limited to 'fs/verity/open.c')
-rw-r--r-- | fs/verity/open.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/verity/open.c b/fs/verity/open.c index 3636a1ed8e2c..63d1004b688c 100644 --- a/fs/verity/open.c +++ b/fs/verity/open.c @@ -122,22 +122,32 @@ out_err: return err; } -/* Compute the file measurement by hashing the fsverity_descriptor. */ +/* + * Compute the file measurement by hashing the fsverity_descriptor excluding the + * signature and with the sig_size field set to 0. + */ static int compute_file_measurement(const struct fsverity_hash_alg *hash_alg, - const struct fsverity_descriptor *desc, + struct fsverity_descriptor *desc, u8 *measurement) { - return fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), measurement); + __le32 sig_size = desc->sig_size; + int err; + + desc->sig_size = 0; + err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), measurement); + desc->sig_size = sig_size; + + return err; } /* * Validate the given fsverity_descriptor and create a new fsverity_info from - * it. + * it. The signature (if present) is also checked. */ struct fsverity_info *fsverity_create_info(const struct inode *inode, - const void *_desc, size_t desc_size) + void *_desc, size_t desc_size) { - const struct fsverity_descriptor *desc = _desc; + struct fsverity_descriptor *desc = _desc; struct fsverity_info *vi; int err; @@ -153,8 +163,7 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode, return ERR_PTR(-EINVAL); } - if (desc->sig_size || - memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) { + if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) { fsverity_err(inode, "Reserved bits set in descriptor"); return ERR_PTR(-EINVAL); } @@ -198,6 +207,8 @@ struct fsverity_info *fsverity_create_info(const struct inode *inode, pr_debug("Computed file measurement: %s:%*phN\n", vi->tree_params.hash_alg->name, vi->tree_params.digest_size, vi->measurement); + + err = fsverity_verify_signature(vi, desc, desc_size); out: if (err) { fsverity_free_info(vi); |