lkml.org 
[lkml]   [2022]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 1/5] fs-verity: define a function to return the integrity protected file digest
    Date
    Define a function named fsverity_get_digest() to return the verity file
    digest and the associated hash algorithm (enum hash_algo).

    This assumes that before calling fsverity_get_digest() the file must have
    been opened, which is even true for the IMA measure/appraise on file
    open policy rule use case (func=FILE_CHECK). do_open() calls vfs_open()
    immediately prior to ima_file_check().

    Acked-by: Eric Biggers <ebiggers@google.com>
    Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
    ---
    fs/verity/Kconfig | 1 +
    fs/verity/fsverity_private.h | 7 ------
    fs/verity/measure.c | 43 ++++++++++++++++++++++++++++++++++++
    include/linux/fsverity.h | 18 +++++++++++++++
    4 files changed, 62 insertions(+), 7 deletions(-)

    diff --git a/fs/verity/Kconfig b/fs/verity/Kconfig
    index 24d1b54de807..54598cd80145 100644
    --- a/fs/verity/Kconfig
    +++ b/fs/verity/Kconfig
    @@ -3,6 +3,7 @@
    config FS_VERITY
    bool "FS Verity (read-only file-based authenticity protection)"
    select CRYPTO
    + select CRYPTO_HASH_INFO
    # SHA-256 is implied as it's intended to be the default hash algorithm.
    # To avoid bloat, other wanted algorithms must be selected explicitly.
    # Note that CRYPTO_SHA256 denotes the generic C implementation, but
    diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h
    index a7920434bae5..c6fb62e0ef1a 100644
    --- a/fs/verity/fsverity_private.h
    +++ b/fs/verity/fsverity_private.h
    @@ -14,7 +14,6 @@

    #define pr_fmt(fmt) "fs-verity: " fmt

    -#include <crypto/sha2.h>
    #include <linux/fsverity.h>
    #include <linux/mempool.h>

    @@ -26,12 +25,6 @@ struct ahash_request;
    */
    #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 SHA512_DIGEST_SIZE
    -
    /* A hash algorithm supported by fs-verity */
    struct fsverity_hash_alg {
    struct crypto_ahash *tfm; /* hash tfm, allocated on demand */
    diff --git a/fs/verity/measure.c b/fs/verity/measure.c
    index f0d7b30c62db..e99c00350c28 100644
    --- a/fs/verity/measure.c
    +++ b/fs/verity/measure.c
    @@ -57,3 +57,46 @@ int fsverity_ioctl_measure(struct file *filp, void __user *_uarg)
    return 0;
    }
    EXPORT_SYMBOL_GPL(fsverity_ioctl_measure);
    +
    +/**
    + * fsverity_get_digest() - get a verity file's digest
    + * @inode: inode to get digest of
    + * @digest: (out) pointer to the digest
    + * @alg: (out) pointer to the hash algorithm enumeration
    + *
    + * Return the file hash algorithm and digest of an fsverity protected file.
    + * Assumption: before calling fsverity_get_digest(), the file must have been
    + * opened.
    + *
    + * Return: 0 on success, -errno on failure
    + */
    +int fsverity_get_digest(struct inode *inode,
    + u8 digest[FS_VERITY_MAX_DIGEST_SIZE],
    + enum hash_algo *alg)
    +{
    + const struct fsverity_info *vi;
    + const struct fsverity_hash_alg *hash_alg;
    + int i;
    +
    + vi = fsverity_get_info(inode);
    + if (!vi)
    + return -ENODATA; /* not a verity file */
    +
    + hash_alg = vi->tree_params.hash_alg;
    + memset(digest, 0, FS_VERITY_MAX_DIGEST_SIZE);
    +
    + /* convert the verity hash algorithm name to a hash_algo_name enum */
    + i = match_string(hash_algo_name, HASH_ALGO__LAST, hash_alg->name);
    + if (i < 0)
    + return -EINVAL;
    + *alg = i;
    +
    + if (WARN_ON_ONCE(hash_alg->digest_size != hash_digest_size[*alg]))
    + return -EINVAL;
    + memcpy(digest, vi->file_digest, hash_alg->digest_size);
    +
    + pr_debug("file digest %s:%*phN\n", hash_algo_name[*alg],
    + hash_digest_size[*alg], digest);
    +
    + return 0;
    +}
    diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
    index b568b3c7d095..9a1b70cc7318 100644
    --- a/include/linux/fsverity.h
    +++ b/include/linux/fsverity.h
    @@ -12,8 +12,16 @@
    #define _LINUX_FSVERITY_H

    #include <linux/fs.h>
    +#include <crypto/hash_info.h>
    +#include <crypto/sha2.h>
    #include <uapi/linux/fsverity.h>

    +/*
    + * 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 SHA512_DIGEST_SIZE
    +
    /* Verity operations for filesystems */
    struct fsverity_operations {

    @@ -131,6 +139,9 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *arg);
    /* measure.c */

    int fsverity_ioctl_measure(struct file *filp, void __user *arg);
    +int fsverity_get_digest(struct inode *inode,
    + u8 digest[FS_VERITY_MAX_DIGEST_SIZE],
    + enum hash_algo *alg);

    /* open.c */

    @@ -170,6 +181,13 @@ static inline int fsverity_ioctl_measure(struct file *filp, void __user *arg)
    return -EOPNOTSUPP;
    }

    +static inline int fsverity_get_digest(struct inode *inode,
    + u8 digest[FS_VERITY_MAX_DIGEST_SIZE],
    + enum hash_algo *alg)
    +{
    + return -EOPNOTSUPP;
    +}
    +
    /* open.c */

    static inline int fsverity_file_open(struct inode *inode, struct file *filp)
    --
    2.27.0
    \
     
     \ /
      Last update: 2022-03-25 23:40    [W:2.967 / U:0.752 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site